Search code examples
reactjsreact-contextside-effectsreact-strictmode

Does change in state unmount functional component


I know that change in state triggers re-rendering of component. So my question is that, does change in state also unmount function component as part of re-rendering process?

main.jsx

const Fullnote = () => {
    const notes = useContext(NotesContext);
    const [note, setNote] = useState(INITIAL_VALUE);
    const { noteId } = useParams();

    useEffect(() => {
        notes.forEach(data => {
            if (data.id === noteId) setNote(data)
        });
  
        return ( () => console.log("return"))

    });


    return (
          <>
              ......
          </>
    )

}

in above code snippet, Here we are getting array of object from context. Each object in that array ha unique id. We are also taking noteId from url. as soon as component mount useEffect runs and we set state which matches noteId.

will console.log("return") run after setState()?


Solution

  • So my question is that, does change in state also unmount function component as part of re-rendering process?

    will console.log("return") run after setState()?

    These are two different questions: Will it unmount? No, the component will not unmount. Only the parent component can make this component unmount. It would do this by ceasing to render a <Fullnote />, or by changing the key on the <Fullnote key={something} />

    However it will log "return". After your component rerenders it will run effects, and just before it runs an effect it runs the cleanup code from the previous render's effects. So the cleanup code from the previous render will run, logging "return".

    If you want to limit when a useEffect runs you can provide a dependency array as the second argument to the useEffect. If none of the values in the array have changed, then the effect does not re-run and thus does not need to teardown the previous effect.

    useEffect(() => {
      // ...
    }, [notes, noteId]);
    

    P.S, if the only place you call setNote is in the useEffect then note shouldn't be a separate state. Instead you can calculate note during rendering. This will make the code more concise, more performant (because it no longer needs a double render), and will eliminate the point in time where the values are out of sync.

    const Fullnote = () => {
      const notes = useContext(NotesContext);
      const { noteId } = useParams();
      const note = notes.find(data => data.id === nodeId);
    
      return (
        <>
          ......
        </>
      )
    }
    

    (if you do call setNote in the code you've omitted, then this advice won't apply)