Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to use lifecycle methods with hooks in React?

I have gone through hooks introduced in react v16.7.0.

https://reactjs.org/docs/hooks-intro.html

So my understanding about hooks is we can play with state in functional component without writing class components in react. This is really amazing feature.

But I am not getting clear picture about using hooks in functional components.

   import { useState } from 'react';

   function Example() {
   const [count, setCount] = useState(0);

    return (
      <div>
        <p>You clicked {count} times</p>
        <button onClick={() => setCount(count + 1)}>
         Click me
        </button>
      </div>
   );
  }

how can I use life cycle methods in the above functional component if I use hooks?

like image 895
Hemadri Dasari Avatar asked Nov 08 '18 19:11

Hemadri Dasari


People also ask

What are the life cycle hooks in React?

Each component in React has a lifecycle which you can monitor and manipulate during its three main phases. The three phases are: Mounting, Updating, and Unmounting.

Do hooks replace lifecycle methods?

The useEffect Hook allows us to replace repetitive component lifecycle code. Essentially, a Hook is a special function that allows you to “hook into” React features. Hooks are a great solution if you've previously written a functional component and realize that you need to add state to it.

Which React hook is used to handle lifecycle methods in a functional component?

If you're familiar with React class lifecycle methods, you can think of useEffect Hook as componentDidMount , componentDidUpdate , and componentWillUnmount combined. There are two common kinds of side effects in React components: those that don't require cleanup, and those that do.

How many lifecycle hooks are in React?

To get through this phase, four lifecycle methods are called: constructor , static getDerivedStateFromProps , render , and componentDidMount .


2 Answers

Here are examples for the most common lifecycles:

componentDidMount

Pass an empty array as the second argument to useEffect() to run only the callback on mount only.

function Example() {
  const [count, setCount] = useState(0);

  useEffect(() => {
    document.title = `You clicked ${count} times`;
  }, []); // Pass an empty array to run only callback on mount only.

  return (
    <div>
      <p>You clicked {count} times</p>
      <button onClick={() => setCount(count + 1)}>
        Click me
      </button>
    </div>
  );
}

componentDidUpdate (loose)

By passing just the single argument into useEffect, it will run after every render. This is a loose equivalent because there's a slight difference here being componentDidUpdate will not run after the first render but this hooks version runs after every render.

function Example() {
  const [count, setCount] = useState(0);

  useEffect(() => {
    document.title = `You clicked ${count} times`;
  }); // No second argument, so run after every render.

  return (
    <div>
      <p>You clicked {count} times</p>
      <button onClick={() => setCount(count + 1)}>
        Click me
      </button>
    </div>
  );
}

componentDidUpdate (strict)

The difference of this example with the example above is that the callback here would not run on initial render, strictly emulating the semantics of componentDidUpdate. This answer is by Tholle, all credit goes to him.

function Example() {
  const [count, setCount] = useState(0);

  const firstUpdate = useRef(true);
  useLayoutEffect(() => {
    if (firstUpdate.current) {
      firstUpdate.current = false;
      return;
    }

    console.log('componentDidUpdate');
  });

  return (
    <div>
      <p>componentDidUpdate: {count} times</p>
      <button
        onClick={() => {
          setCount(count + 1);
        }}
      >
        Click Me
      </button>
    </div>
  );
}

componentWillUnmount

Return a callback in useEffect's callback argument and it will be called before unmounting.

function Example() {
  const [count, setCount] = useState(0);

  useEffect(() => {
    // Return a callback in useEffect and it will be called before unmounting.
    return () => {
      console.log('componentWillUnmount!');
    };
  }, []);

  return (
    <div>
      <p>You clicked {count} times</p>
      <button onClick={() => setCount(count + 1)}>
        Click me
      </button>
    </div>
  );
}

shouldComponentUpdate

You can already achieve this on the component level using React.PureComponent or React.memo. For preventing rerendering of the child components, this example is taken from React docs:

function Parent({ a, b }) {
  // Only re-rendered if `a` changes:
  const child1 = useMemo(() => <Child1 a={a} />, [a]);
  // Only re-rendered if `b` changes:
  const child2 = useMemo(() => <Child2 b={b} />, [b]);
  return (
    <>
      {child1}
      {child2}
    </>
  )
}

getDerivedStateFromProps

Again, taken from the React docs

function ScrollView({row}) {
  let [isScrollingDown, setIsScrollingDown] = useState(false);
  let [prevRow, setPrevRow] = useState(null);

  if (row !== prevRow) {
    // Row changed since last render. Update isScrollingDown.
    setIsScrollingDown(prevRow !== null && row > prevRow);
    setPrevRow(row);
  }

  return `Scrolling down: ${isScrollingDown}`;
}

getSnapshotBeforeUpdate

No equivalent for hooks yet.

componentDidCatch

No equivalent for hooks yet.

like image 98
Yangshun Tay Avatar answered Sep 22 '22 05:09

Yangshun Tay


Well, you don't really have lifecycle methods. =) But you could use the effect hook as shown here https://reactjs.org/docs/hooks-effect.html

The effect hook will be able to replicate the behavior of componentDidMount, componentDidUpdate, and componentWillUnmount

So you really don't need lifecycle methods in the component. The effect hook is taking their place instead. =)

Read the link above and you will get a few examples on how they work.

like image 42
weibenfalk Avatar answered Sep 24 '22 05:09

weibenfalk