【问题标题】:Update State then Redirect with React Router Dom使用 React Router Dom 更新状态然后重定向
【发布时间】:2020-08-08 03:06:50
【问题描述】:

我在一个项目中使用 React 16.12.0,React Router DOM 5.1.2,并且只有在成功更新状态后才能重定向。基本上我有一个按钮,当点击时,我想用用户选择的信息更新状态,然后导航到主页并显示横幅。我正在使用封装在最高组件级别之一的 React Hook useContext,以及来自 React Router Dom 的历史对象。

预期行为:

  • 上下文状态属性“showBanner”设置为 true
  • 导航到“/”页面

现有行为:

  • 导航到“/”页面
  • 上下文状态属性“showBanner”仍然为假

这是代码的sn-p:

// Import statements - useHistory() from react-router-dom, useContext from react, etc.

const browse = (props) => {
  const {globalState, dispatchGlobalState} = useContext(myContext);
  const history = useHistory();

  const handleButtonClick = (e) => {
    dispatchGlobalState( { type: 'showBanner', payload: true } );
    history.push('/');
  }

  return (
   <button onClick={handleButtonClick}>Click Me</button>
  )

我也试过用 Promise 包装调度,但没有运气......

  const handleButtonClick = (e) => {
    new Promise( (resolve, reject) ) => {
      dispatchGlobalState( { type: 'showBanner', payload: true } );
    })
    .then( () => {
      history.push('/');
    }));

我也尝试过使用本地状态有条件地渲染元素,但也没有运气。有谁知道我可能做错了什么 - 我如何告诉 React 首先进行我所有的状态更新,并且只有在完成后,然后重定向到另一个页面?

【问题讨论】:

  • 我认为那里发生了竞争情况。虽然这不是最佳实践,但您可以尝试 setTimeout。即 setTimeout(()=>history.push('/'),0)
  • 是的,这完全是一种竞争条件。由于两者都是异步操作的,因此有时会显示横幅(意味着首先更新全局状态,然后发生重定向)。并且有时它不显示(意味着在全局状态有机会更新之前首先触发重定向)。
  • setTimeOut 工作了吗?
  • 我认为我们遇到了同样的问题。即使使用了 setTimeOut,仍然不能保证 dispatchGobalState 会在它之前成功运行,对吧?

标签: javascript reactjs react-router


【解决方案1】:

您可以使用 useEffect 来触发重定向。 useEffect 的依赖项将是您的 globalState,当更改发生重定向时。

确保不要在初始渲染时调用 useEffect。

const browse = (props) => {
  const {globalState, dispatchGlobalState} = useContext(myContext);
  const history = useHistory();
  const isInitialRender = useRef(true);

  const handleButtonClick = (e) => {
    dispatchGlobalState( { type: 'showBanner', payload: true } );
  }

  useEffect(() => {
      if(!isInitialRender.current) {
         history.push('/');
      }else {
         isInitialRender.current = false;
      }

  }, [globalState])
  return (
   <button onClick={handleButtonClick}>Click Me</button>
  )

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2022-06-24
    • 1970-01-01
    • 2017-07-04
    • 2019-06-28
    • 2018-02-04
    • 2019-02-05
    • 1970-01-01
    • 2018-05-21
    相关资源
    最近更新 更多