【问题标题】:React issue with props.history.push ignore setState since setState is async反应问题与 props.history.push 忽略 setState 因为 setState 是异步的
【发布时间】:2020-06-23 22:29:56
【问题描述】:

我在这里有两条路线HomeResultHome 监控它的两个状态 idcount。在Home 内部有一个嵌套组件Page,它的状态为check,并呈现一个按钮。按钮单击触发事件:1) 如果check 为真,则增加count,2) 如果id id,否则将count 传递到不同的路由Result (props.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;

【问题讨论】:

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


    【解决方案1】:

    好的,我想出了一种方法,通过将props.history.push 移动到监视id 变化的useEffect 来使其工作。不确定这是否是最佳做法。请告诉我。

    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;
    

    【讨论】:

    • 在传统的类组件案例中尝试componentDidUpdate方法。
    【解决方案2】:

    如果你想获取当前值传递给历史:

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

    还需要增加当前值:

    setCount(current => current + 1);
    

    id 的想法相同。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2019-02-13
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-10-10
      • 2021-11-13
      • 2019-10-21
      • 1970-01-01
      相关资源
      最近更新 更多