使用props.history.push反应问题忽略setState,因为setState是异步的

时间:2020-06-23 22:29:56

标签: javascript reactjs asynchronous react-router-dom setstate

我在HomeResult上有两条路线。 Home监视其两个状态idcount。在Home内部,有一个嵌套组件Page,其状态为check,并呈现一个按钮。单击按钮可触发事件:1)如果count为true,则递增check; 2)如果id <3,则递增id;否则,将count传递给另一个路由Resultprops.history.push)。

为了简化此示例中的问题,我将check设置为true。由于id从0开始,所以当Route更改时,count应该是3,但我在这里只有2。我试图先同步调用setState来递增count,然后再传递给Result,但props.history.push会忽略setState并自行执行。

处理这种情况或类似情况(不修改组件或状态层次结构)的最佳实践是什么? 请在下面找到示例代码和屏幕截图。

App.js

<BrowserRouter>
  <Switch>
    <Route path="/home" component={Home} />
    <Route path="/result" component={Result} />
    <Redirect from="/" to="/home" />
  </Switch>
</BrowserRouter>;

Home.js

const Home = (props) => {
  const [id, setId] = useState(0);
  const [count, setCount] = useState(0);

  const handleCount = () => {
    setCount(count + 1);
  };

  const handleNextId = () => {
    if (id >= 3) {
      props.history.push({
        pathname: "/result",
        state: { count: count },
      });
    } else {
      setId(id + 1);
    }
  };

  return (
    <div>
      <div>id: {id}</div>
      <div>count: {count}</div>
      <br />
      <Page count={handleCount} nextId={handleNextId} />
    </div>
  );
};

export default Home;

Page.js

const Page = (props) => {
  const [check, setCheck] = useState(true);

  const handleCheck = () => {
    if (check) {
      props.count();
    }
    props.nextId();
  };

  return (
    <button type="text" onClick={handleCheck}>
      next
    </button>
  );
};

export default Page;

enter image description here

2 个答案:

答案 0 :(得分:0)

好的,我想出了一种方法,可以通过将props.history.push移到useEffect来监视id的更改。不知道这是否是最佳做法。请让我知道。

Home.js

const Home = (props) => {
  const [id, setId] = useState(0);
  const [count, setCount] = useState(0);

  useEffect(() => {
    if (id >= 3) {
      props.history.push({
        pathname: "/result",
        state: { count: count },
      });
    }
  }, [id]);

  const handleCount = () => {
    setCount(count + 1);
  };

  const handleNextId = () => {
    setId(id + 1);
  };

  return (
    <div>
      <div>id: {id}</div>
      <div>count: {count}</div>
      <br />
      <Page count={handleCount} nextId={handleNextId} />
    </div>
  );
};

export default Home;

enter image description here

答案 1 :(得分:-1)

如果要获取当前值以传递到历史记录:

let currentCount;
setCount(current => {
   currentCount = current;
   return current;
});
props.history.push({
        pathname: "/result",
        state: { count: currentCount },
      });

还需要增加当前值:

setCount(current => current + 1);

对ID的想法相同。