javascriptreactjsdraftjsreact-draft-wysiwyg

React Draft Wysiwyg always stays on undefined


I have an useEffect hook which will do an axios get api request and store in an useState

const [apiResponse, setApiResponse] = useState([]);

useEffect(() => {
    ... // inside of .then()
    setApiResponse(data.data.payload);
    ....
},[]);

apiResponse has an array of Object

[
    {
        userName: "user Name",
        description: "<p>lorem ipsum lorem ipsum lorem ipsum</p>",
        selected: "Yes",
    }
]

React Draft Wysiwyg

const blocksFromHTML = convertFromHTML(`${apiResponse.description}`);
const state = ContentState.createFromBlockArray(
    blocksFromHTML.contentBlocks,
    blocksFromHTML.entityMap
);

const [editorState, setEditorState] = useState(() =>
    EditorState.createWithContent(state)
);

const onEditorStateChange = (editorState) => {
    setEditorState(editorState);
    return draftToHtml(convertToRaw(editorState.getCurrentContent()));
};
....
return (
    ....
    <Editor
        toolbarClassName="toolbarClassName"
        wrapperClassName="ChannelDesscription"
        editorClassName="editorClassName"
        editorState={editorState}
        defaultEditorState={editorState}
        onEditorStateChange={onEditorStateChange}
    />
    ...
)

I am getting undefined printed on the Editor.

On console log, i am undefined on the first render and then the value is printed on the console.. but inside the editor it remains as undefined.

console.log(apiResponse.description)

What mistake am i making here ?

Thank you.


Solution

  • I can't verify that this is the issue based on the code, but my guess is the issue is with how initial state works with useState

    Signature

    const [state, setState] = useState(initialState)
    

    Here initialState is only used to initialize the state--changes to initialState on subsequent renders do not impact the value of state.

    First render

    const [state, setState] = useState(0)
    console.log(state) // 0
    

    Second render

    const [state, setState] = useState(1)
    console.log(state) // 0
    

    To change the state after the first render, you have to call setState.

    Third render

    const [state, setState] = useState(1)
    console.log(state) // 0
    setState(3)
    

    Fourth render

    const [state, setState] = useState(1)
    console.log(state) // 3
    

    My inkling is that in your case editorState is initialised before the request for the data has been completed--which means that it gets initialised with an undefined value. You have to use some other mechanism that initialValue to provide the value of the response to the state if you are not able to wait for the response to resolve before you initialise the editor state.

    You can test out whether this is the issue by setting the editor state in the useEffect where you store the response.

    useEffect(() => {
        ... // inside of .then()
        setApiResponse(data.data.payload);
        
        const { contentBlocks, entityMap } = convertFromHTML(apiResponse.description);
        setEditorState(
            EditorState.createWithContent(
                ContentState.createFromBlockArray(
                    contentBlocks,
                    entityMap
                )
            )
         )
        ....
    },[]);
    

    In your final implementation, make sure that you do not override the editor state by accident after the user has already made changes.