设置状态后反应挂钩相当于回调函数

时间:2019-02-26 23:28:15

标签: javascript reactjs

在设置状态时,在react(在钩子之前)的反应中,我们可以在状态设置为此类之后调用一个函数:

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

与钩子等效吗?

我尝试这样做

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

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

但这没用

有人知道解决方案吗?

2 个答案:

答案 0 :(得分: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;
    }

    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>

答案 1 :(得分:0)

您可以使用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>
  );
};

如果您要寻找一种开箱即用的解决方案,请签出stackbliz,其用途类似于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

安装