40

我有一条在检查这样的条件后重定向的路线

<Route exact path="/" render={()=>(
Store.isFirstTime ? <Redirect to="intro" /> : <Home state={Store}/>)}/>

当条件为真但组件未挂载时,url 会发生变化。其余的组件代码如下。

render() {
    return (
      <div>
        ...
        <Route exact path="/" render={()=>(
          Store.isFirstTime ? <Redirect to="intro" /> : <Home state={Store} />         
        )} />
        <Route path="/intro" render={()=>(<IntroWizard state={Store.userInfo}/>)} />
        <Route path="/home" render={()=>(<Home state={Store}/>)} />
        <Route render={()=>(<h1>404 Not Found</h1>)} />
        <Footer />
      </div>
    );
  }

我的应用程序组件包含在 BrowserRouter 中,就像这样

ReactDOM.render(<BrowserRouter>
    <App/>
</BrowserRouter>,
  document.getElementById('root')
);

当我直接在浏览器中点击 url 时,像 'localhost:3000/intro' 组件已成功安装,但是当它通过重定向时,它不会显示该组件。我如何解决它?

编辑

所以缺少一个细节,我尝试创建另一个项目来重现该问题。我的 App 组件是来自 mobx-react 的观察者,它的导出如下所示

let App = observer(class App { ... })
export default App

我已经使用示例代码创建了这个 repo 来重现您可以使用它的问题 https://github.com/mdanishs/mobxtest/

因此,当组件被包装到 mobx-react 观察者中时,重定向不起作用,否则它可以正常工作

4

9 回答 9

53

提问者在 GitHub 上发布了一个问题,并得到了这个显然未发布的隐藏指南(编辑:现已发布),它也帮助了我。我在这里发布它是因为我遇到了同样的问题并希望其他人避免我们的痛苦。

问题是 mobx-react 和 react-redux 都提供了自己的shouldComponentUpdate()函数,这些函数只检查 prop 的变化,但是 react-router 通过上下文发送状态。当位置发生变化时,它不会更改任何道具,因此不会触发更新。

解决此问题的方法是将位置作为道具向下传递。上面的指南列出了几种方法来做到这一点,但最简单的方法是用withRouter()高阶组件包装容器:

export default withRouter(observer(MyComponent))

或者,对于 redux:

export default withRouter(connect(mapStateToProps)(MyComponent))
于 2017-03-20T08:29:35.867 回答
25

您应该只Redirect在您的渲染方法中渲染:

render() {
  return (<Redirect to="/" />);
}

但这是我最喜欢的不使用Redirect组件的解决方案

  1. 进口import { withRouter } from 'react-router-dom';
  2. export default withRouter(MyComponent);
  3. 最后,在您的操作方法中,假设handlingButtonClick
handlingButtonClick = () => {
  this.props.history.push("/") //doing redirect here.
}
于 2019-05-23T08:26:26.043 回答
17

<Redirect />不应该在<Switch></Switch>标签内。

于 2020-03-16T08:07:45.970 回答
6

与其他组件(如翻译提供程序、主题提供程序等)组合路由器时要小心。一段时间后,我发现您的应用程序必须由路由器严格包装,如下所示:

<Provider store={store}>
  <ThemeProvider theme={theme}>
    <TranslationProvider
      namespaces={['Common', 'Rental']}
      translations={translations}
      defaultNS={'Common'}
    >
      <Router>
        <App />
      </Router>
    </TranslationProvider>
  </ThemeProvider>
</Provider>

希望这可以帮助某人

于 2018-01-16T14:07:42.553 回答
3

你在介绍前面少了一个 /

<Route exact path="/" render={()=>(
  Store.isFirstTime ? <Redirect to="/intro" /> : <Home state={Store} />         
)} />
于 2017-03-18T17:00:54.187 回答
2

你可以这样尝试:

首先:将“withRouter”导入组件,如下所示:

import { withRouter } from "react-router-dom";

然后在您的组件导出组件的末尾,如下所示:

export default withRouter(VerifyCode);

然后您可以将此代码添加到您的函数中:

 verify(e) {
    // after sever get 200
    this.props.history.push('/me/');
}

祝你好运

于 2020-05-13T10:54:49.873 回答
2

添加“精确”以重定向

例子 :

<Switch>
   <Route exact path="/">
      <Redirect to="/home" />
   </Route>
<Switch>
于 2021-07-25T16:35:35.200 回答
0

我用 ReactJS 重定向研究了 3 个小时,这里是重定向的最佳方法,我创建了一个这样的模块:

import { useHistory, withRouter } from "react-router-dom";

const Redirect = (props: any) => { 
    const to = (props.to || '/');
    let history = useHistory();
        history.push(to);
        window.location.reload();
    return (
      <>
      </>
     )
   }
export default withRouter(Redirect);

它工作完美!您可以在其他文件中使用!像这样:

    export default function RedirectExample() {
      return (
        <Router>
          <Switch>
            <Route path="/page/2">
              <QueryPage />
            </Route>
            <Route path="/page">
              <MyRedirect to="/" />
            </Route>
          </Switch>
        </Router>
      );
    }
于 2021-08-28T16:02:14.683 回答
0
  const App = ({history}) =>{

  return history.push('/location')  }
于 2021-03-13T08:35:32.130 回答