Skip to content Skip to sidebar Skip to footer

How To Access State When Component Unmount With React Hooks?

With regular React it's possible to have something like this: class NoteEditor extends React.PureComponent { constructor() { super(); this.state = {

Solution 1:

useState() is a specialized form of useReducer(), so you can substitute a full reducer to get the current state and get around the closure problem.

NoteEditor

importReact, { useEffect, useReducer } from"react";

functionreducer(state, action) {
  switch (action.type) {
    case"set":
      return action.payload;
    case"unMount":
      console.log("This note has been closed: " + state); // This note has been closed: 201break;
    default:
      thrownewError();
  }
}

functionNoteEditor({ initialNoteId }) {
  const [noteId, dispatch] = useReducer(reducer, initialNoteId);

  useEffect(functionlogBeforeUnMount() {
    return() =>dispatch({ type: "unMount" });
  }, []);

  useEffect(functionchangeIdSideEffect() {
    setTimeout(() => {
      dispatch({ type: "set", payload: noteId + 1 });
    }, 1000);
  }, []);

  return<div>{noteId}</div>;
}
exportdefaultNoteEditor;

App

importReact, { useState, useEffect } from"react";
import"./styles.css";
importNoteEditorfrom"./note-editor";

exportdefaultfunctionApp() {
  const [notes, setNotes] = useState([100, 200, 300]);

  useEffect(functionremoveNote() {
    setTimeout(() => {
      setNotes([100, 300]);
    }, 2000);
  }, []);

  return (
    <divclassName="App"><h1>Hello CodeSandbox</h1><h2>Start editing to see some magic happen!</h2>
      {notes.map(note => (
        <NoteEditorkey={`Note${note}`} initialNoteId={note} />
      ))}
    </div>
  );
}

Solution 2:

useRef() to the rescue.

Since the ref is mutable and exists for the lifetime of the component, we can use it to store the current value whenever it is updated and still access that value in the cleanup function of our useEffect via the ref's value .current property.

So there will be an additional useEffect() to keep the ref's value updated whenever the state changes.

Sample snippet

const [value, setValue] = useState();
const valueRef = useRef();

useEffect(() => {
  valueRef.current = value;
}, [value]);

useEffect(() => {
  returnfunctioncleanup() {
    console.log(valueRef.current);
  };
}, []);

Thanks to the author of https://www.timveletta.com/blog/2020-07-14-accessing-react-state-in-your-component-cleanup-with-hooks/. Please refer this link for deep diving.

Solution 3:

I wanted to chime in with an answer for this in case someone else runs into this. If you need more than one value in your useEffect unmount function, it's important to make sure that the correct dependencies are being used. So the accepted answer works fine because it's just one dependency, but start including more dependencies, and it gets complicated. The amount of useRef's you need get out of hand. So instead, what you can do is a useRef that is the unmount function itself, and call that when you unmount the component:

importReact, { useRef, useState, useContext, useCallback, useEffect } from'react';
import { Heading, Input } from'../components';
import { AppContext } from'../../AppContext';

exportconstTitleSection: React.FC = ({ thing }) => {
  const { updateThing } = useContext(AppContext);
  const [name, setName] = useState(thing.name);
  const timer = useRef(null);
  const onUnmount = useRef();

  const handleChangeName = useCallback((event) => {
    setName(event.target.value);

    timer.current !== null && clearTimeout(timer.current);
    timer.current = setTimeout(() => {
      updateThing({
        name: name || ''
      });
      timer.current = null;
    }, 1000);
  }, [name, updateThing]);

  useEffect(() => {
    onUnmount.current = () => {
      if (thing?.name !== name) {
        timer.current !== null && clearTimeout(timer.current);
        updateThing({
          name: name || '',
        });
        timer.current = null;
      }
    };
  }, [thing?.name, name, updateThing]);

  useEffect(() => {
    return() => {
      onUnmount.current?.();
    };
  }, []);

  return (
    <><Headingas="h1"fontSize="md"style={{marginBottom:5 }}>
        Name
      </Heading><Inputplaceholder='Grab eggs from the store...'value={name}onChange={handleChangeName}variant='white'
      /></>
  );
};

Post a Comment for "How To Access State When Component Unmount With React Hooks?"