How to use componentDidMount, componentWillUnmount and declare the initial state in functional components?

Asked

Viewed 49 times

1

I’m trying to make a class component to functional component conversion.

The code I have is:

  constructor(props) {
    super(props);

    this.state = SelectionToolbarStore.getState();
  }

  componentDidMount() {
    SelectionToolbarStore.addChangeListener(this.handleChange);
  }

  componentWillUnmount() {
    SelectionToolbarStore.removeChangeListener(this.handleChange);
  }

  handleChange = () => {
    this.setState(SelectionToolbarStore.getState());
  };
...

What I’ve done so far:

const SelectionToolbar = () => {
  // constructor(props) {
  //   super(props);

  //   this.state = SelectionToolbarStore.getState();
  // }

  componentDidMount() {
    SelectionToolbarStore.addChangeListener(this.handleChange);
  }

  componentWillUnmount() {
    SelectionToolbarStore.removeChangeListener(this.handleChange);
  }

  handleChange = () => {
    this.setState(SelectionToolbarStore.getState());
  };

What I want to do now is turn these componentDidMount() and componentWillUnmount() in Hooks, but I’m not sure how.

I also want to convert this.state = SelectionToolbarStore.getState() for const [state, setState] = useState(SelectionToolbarStore.getState()); That’s right, I don’t know if it makes sense.

  • I don’t know where it comes from SelectionToolbarStore, but what you suggested seems right. What’s the problem in the useState? Your question is, then, only about componentDidMount() and componentWillUnmount()?

  • The SelectionToolbarStorecomes from my teachers. The question is about componentDidMount()and componentWillUnmount()yes. Because although the site did not break the functionality I wanted it to occur it does not happen

1 answer

2


Hooks

You will replace the lifecycle functions with Hooks. The status too. Therefore, read What are React Hooks? if you have any questions about them in general.

useEffect

The hook useEffect can behave in a similar way to componentDidMount and componentWillUnmount. Can because it has an array of dependencies, which indicates when the callback passed should be run again.

The hook runs after each render, but the callback runs only if something within the dependency array is modified. So, if the array is empty [], will function as the componentDidMount.

In the useEffect, we can also return a callback to "clean" the effect. React will execute the clean up when the component disassembles. However, as I mentioned earlier, the useEffect is executed in all surrender, not just once. This is why React also cleans the effect of previous renders before performing the effect again on the next render.

In summary, the clean up is executed before the effect is triggered again. If the dependency array is empty, the behavior will be like the componentWillUnmount.

function Component() {
  // O primeiro argumento é o callback a ser executado.
  // O segundo argumento é um array vazio, que fará com que o callback seja executado
  // apenas no primeiro render.
  useEffect(() => {
    const handleChange = () => {
      this.setState(SelectionToolbarStore.getState());
    };
    SelectionToolbarStore.addChangeListener(handleChange);

    return () => {
      // Aqui o clean up será executado apenas quando o componente for desmontar
      SelectionToolbarStore.removeChangeListener(handleChange);
    }
  }, []);

  return null;
}

useCallback

Note that I have declared the function handleChange within the useEffect, since it is only used there. Otherwise, you would need to declare out and use as hook dependency.

In that case, you could make use of the useCallback so that React doesn’t create a new function reference for each rendering. I talk a little bit about this in that reply. The code would look like this:

function Component() {
  const handleChange = useCallback(() => {
    this.setState(SelectionToolbarStore.getState());
  }, []);

  useEffect(() => {
    SelectionToolbarStore.addChangeListener(handleChange);

    return () => {
      SelectionToolbarStore.removeChangeListener(handleChange);
    }
  }, [handleChange]);

  return null;
}

This code will work the same way as the other, with the dependency array empty. This is because the function reference will be created only once, thanks to the useCallback, which will be at first render. It is important to understand this.

useState

The initial value of useState must be declared as informed in the question. The initial value is set in the first render. Can be an import, can be passed by prop, can be a constant.

import { valor1 } from './valor1';

function Component({ valor2 }) {
  const [val1, setVal1] = useState(valor1);
  const [val2, setVal2] = useState(valor2);
  const [val3, setVal3] = useState('Qualquer coisa');

  return null;
}

Browser other questions tagged

You are not signed in. Login or sign up in order to post.