React hook equivalent to callback function after setting state

前端 未结 2 642
执笔经年
执笔经年 2021-02-07 07:03

In react (before hooks) when we set state we could call a function after state had been set as such:

this.setState({}, () => {//Callback})

W

相关标签:
2条回答
  • 2021-02-07 07:22

    The useEffect hook can be used to invoke a function when some state change. If you pass it currentRange in an array as second argument, the function will only be invoked when currentRange change.

    You can also create your own custom hook that uses the useRef hook to keep track of if it's the first time the effect is being run, so that you can skip the first invocation.

    Example

    const { useRef, useState, useEffect } = React;
    
    function useEffectSkipFirst(fn, arr) {
      const isFirst = useRef(true);
    
      useEffect(() => {
        if (isFirst.current) {
          isFirst.current = false;
          return;
        }
    
        return fn();
      }, arr);
    }
    
    function App() {
      const [currentRange, setCurrentRange] = useState("24h");
    
      useEffectSkipFirst(
        () => {
          console.log("hi");
        },
        [currentRange]
      );
    
      return (
        <button
          onClick={() => setCurrentRange(Math.floor(Math.random() * 24) + 1 + "h")}
        >
          Change range ({currentRange})
        </button>
      );
    }
    
    ReactDOM.render(<App />, document.getElementById("root"));
    <script src="https://unpkg.com/react@16/umd/react.development.js"></script>
    <script src="https://unpkg.com/react-dom@16/umd/react-dom.development.js"></script>
    
    <div id="root"></div>

    0 讨论(0)
  • 2021-02-07 07:22

    You can use useEffect/useLayoutEffect to achieve this:

    const SomeComponent = () => {
      const [count, setCount] = React.useState(0)
    
      React.useEffect(() => {
        if (count > 1) {
          document.title = 'Threshold of over 1 reached.';
        } else {
          document.title = 'No threshold reached.';
        }
      }, [count]);
    
      return (
        <div>
          <p>{count}</p>
    
          <button type="button" onClick={() => setCount(count + 1)}>
            Increase
          </button>
        </div>
      );
    };
    

    If you are looking for an out of the box solution, check out this custom hook that works like useState but accepts as second parameter a callback function:

    import useStateWithCallback from 'use-state-with-callback';
    
    const SomeOtherComponent = () => {
      const [count, setCount] = useStateWithCallback(0, count => {
        if (count > 1) {
          document.title = 'Threshold of over 1 reached.';
        } else {
          document.title = 'No threshold reached.';
        }
      });
    
      return (
        <div>
          <p>{count}</p>
    
          <button type="button" onClick={() => setCount(count + 1)}>
            Increase
          </button>
        </div>
      );
    };
    

    It can be installed via npm install use-state-with-callback

    0 讨论(0)
提交回复
热议问题