设置状态后react-hooks相当于回调函数

IT技术 javascript reactjs
2021-05-07 14:52:28

在 React(钩子之前)设置状态时,我们可以在状态设置后调用函数,如下所示:

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

这与钩子的等价物是什么?

我试过这样做

const [currentRange, setCurrentRange] = useState("24h");

setCurrentRange(someRange, () => console.log('hi')) 

但这没有用

有人知道解决方案吗?

2个回答

所述useEffect钩子可用于调用函数时一些状态改变。如果将它currentRange作为第二个参数传入数组,则仅在currentRange更改时调用该函数

您还可以创建自己的自定义钩子,使用useRef钩子来跟踪效果是否是第一次运行,以便您可以跳过第一次调用。

例子

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>

您可以使用 useEffect/useLayoutEffect 来实现这一点:

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>
  );
};

如果您正在寻找开箱即用的解决方案,请查看这个自定义钩子,它的工作方式类似于 useState 但接受回调函数作为第二个参数:

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>
  );
};

它可以通过安装 npm install use-state-with-callback