React getting state

I am currently creating my own mini-bbcode editor for my ReactJS application. I use functional components. In the TextEditor.jsx file I have the following code that handles the textarea.

const [bbcodeText, setBbcodeText] = useState("");

const update = (e) => {
    setSelection(null);
    setBbcodeText(e.target.value);
    if (typeof props.onChange == 'function') {
        props.onChange(e.target.value);
    }
}

<textarea className="form-input forum__body-input" ref={textAreaRef} value={bbcodeText} onChange={update} />

The above works correctly, however I installed [emoji-mart] 1 to have access to the option to place emojis in the textarea, for which I use the following code:

const handleEmoji = (emoji) => {
        let newText = bbcodeText + " " + emoji.native;
        setBbcodeText(newText);
    }
<Picker title="Emojis" emoji="grinning" set='apple'  style={{width: '100%'}} onSelect={handleEmoji} />

The textarea updates correctly, the problem is that this TextEditor component accesses it from a parent component of the form:

 const [bbcode, setBBcode] = useState();
 const update = (v) => {
    setBBcode(v);
};


const handlePost = async() => {
    console.log(bbcode)
}
<TextEditor onChange={update}  onSelect={handleEmoji} />
<button className="button purple" onClick={handlePost}>Agregar respuesta</button>

The problem occurs if I select an emoji and try to access the "bbcode" state, the result is an empty string, but if I write something after it, the emoji is already shown with the text at the end, that is, I need to fire the onChange to display the updated data.

What I need to know is a guide on how to get the updated status, if I only want to insert emojis in the textarea, for example.

In this case bbcode returns undefined if I only use "emojis" but if I write text it works correctly.

Upvotes: 1

Views: 57

Answers (1)

Drew Reese
Drew Reese

Reputation: 202608

I'd suggest moving the onChange callback logic to an useEffect hook with a dependency on the bbcodeText state. This way anything that updates the bbcodeText state value will trigger the effect to invoke the onChange handler to update anything in the parent component.

const [bbcodeText, setBbcodeText] = useState("");

const update = (e) => {
  setSelection(null);
  setBbcodeText(e.target.value);
}

const handleEmoji = (emoji) => {
  setBbcodeText(bbcodeText => bbcodeText + " " + emoji.native);
}

useEffect(() => {
  if (typeof props.onChange == 'function') {
    props.onChange(bbcodeText);
  }
}, [bbcodeText]);

Upvotes: 1

Related Questions