Search code examples
reactjsreact-nativereact-reduxreact-hooksreact-lifecycle

React Hooks and React lifecycle Methods


I am new to reactjs and react native. when started learning the basics, I found various information about the react hooks and react life cycle methods. I know there were 7 lifecycle methods before react 16.3 but now there are just 6 of them. Can anyone elaborate this lifecycle methods and react hooks with some examples. this might help me to learn faster. Thank you


Solution

  • In React classes you had lifecycle functions and state to do things but you didn't have them in functional components. The React defs came up with hooks where you can simplify your code and re use your code better by bundling up certain functionality in a custom hook. This was previously not possible with class components. Even with mix-ins like used in Vue they now have composition api that works similarly to hooks.

    Let's say you want to have counter functionality that will log when a counter changes, have an up and down function and a counter value.

    In a class you need to maintain this.state.counter that you change with this.up and this.down so you could implement this in a Counter class that extends React.Component or React.PureComponent and have a component that uses a counter extends Counter but then that component can still just have one counter. In hooks you can implement a counter with a custom hook and have multiple counters in one component.

    const {
      useState,
      useEffect,
      useCallback,
      useRef,
      memo,
    } = React;
    
    //hooks, also custom hooks always start with "use"
    const useCounter = (name, initialValue = 1) => {
      //local counter value and function to change it
      const [counter, setCounter] = useState(initialValue);
      //ref created on mount with previous counter value
      const countRef = useRef(initialValue);
      //up and down functions created with useCallback so they
      //  will be created on mount and never change
      const up = useCallback(
        () => setCounter((c) => c + 1),
        []
      );
      const down = useCallback(
        () => setCounter((c) => c - 1),
        []
      );
      //effect that will log when counter changes
      useEffect(() => {
        if (countRef.current !== counter) {
          console.log(`counter ${name} changed to`, counter);
          countRef.current = counter;
        }
      }, [counter, name]);
      //return up, down and counter
      return { up, down, counter };
    };
    //using memo makes UP2 a pure component so it'll not re
    //  render since up is created with useCallback and is
    //  not re created therefore the props passed to UP2 
    //  don't change
    const UP2 = memo(function UP2({ up, name }) {
      console.log(`UP2 for ${name} will only render once`);
      return (
        <button
          onClick={() => {
            //state updates are batched in synchronous
            //  event handlers so "chaged to" will log
            //  only once
            up();
            up();
          }}
        >
          +2
        </button>
      );
    });
    
    const App = () => {
      //first counter
      const {
        up: up1,
        down: down1,
        counter: counter1,
      } = useCounter('counter one');
      //second counter
      const {
        up: up2,
        down: down2,
        counter: counter2,
      } = useCounter('counter two', 2);
      return (
        <div>
          <div>
            <button onClick={up1}>UP</button>
            <button onClick={down1}>Down</button>
            <UP2 up={up1} name={'counter one'} />
            {counter1}
          </div>
          <div>
            <button onClick={up2}>UP</button>
            <button onClick={down2}>Down</button>
            <UP2 up={up2} name={'counter two'} />
            {counter2}
          </div>
        </div>
      );
    };
    
    ReactDOM.render(<App />, document.getElementById('root'));
    <script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.8.4/umd/react.production.min.js"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.8.4/umd/react-dom.production.min.js"></script>
    <div id="root"></div>