反应路由器 v4 重定向不起作用

Posted

技术标签:

【中文标题】反应路由器 v4 重定向不起作用【英文标题】:React Router v4 Redirect not working 【发布时间】:2017-08-10 02:22:28 【问题描述】:

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

<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 中,例如 thi

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 观察者中时,重定向不起作用,否则它可以正常工作

【问题讨论】:

您在控制台中看到任何错误吗? @TharakaWijebandara 控制台中没有错误,事实上我只是尝试使用链接,它也不起作用。不知道出了什么问题。 【参考方案1】:

你在 intro 前面少了一个 /

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

【讨论】:

您(或您正在使用的库)是否在任何地方使用 shouldComponentUpdate? github.com/ReactTraining/react-router/blob/v4/packages/… 哇,就是这样。我正在从接受的答案中阅读各种文档,但我只需要/ :)【参考方案2】:

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

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

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

export default withRouter(observer(MyComponent))

或者,对于 redux:

export default withRouter(connect(mapStateToProps)(MyComponent))

【讨论】:

是的,通常 React Router 和 Redux 可以很好地协同工作。但有时,应用程序可能具有在位置更改时不更新的组件(子路由或活动导航链接不更新)。这称为阻止更新。问题是 Redux 实现了 shouldComponentUpdate 并且如果它没有从路由器接收道具,则没有任何迹象表明任何事情发生了变化。这很容易解决。找到连接组件的位置并将其包装在 withRouter 中。 github.com/ReactTraining/react-router/blob/master/packages/…【参考方案3】:

Router 与其他组件(如翻译提供者、主题提供者等)组合时要小心。一段时间后,我发现你的 App 必须由 Router 严格包装,如下所示:

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

希望这对某人有所帮助

【讨论】:

非常感谢,你帮了我很多!就我而言,IntlProvider 是罪魁祸首。我认为这可能是因为上下文或某些shouldComponentUpdate 魔术。 太好了,这对我来说也是个问题,我的路线被包裹在 ThemeProvider 中,导致了这个问题。【参考方案4】:

你应该只在你的渲染方法中渲染Redirect

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

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

    导入import withRouter from 'react-router-dom'; export default withRouter(MyComponent); 最后,在您的操作方法中,假设handlingButtonClick
handlingButtonClick = () => 
  this.props.history.push("/") //doing redirect here.

【讨论】:

它不能解决所有情况。我已经尝试过这两种方法,但它不起作用。所有仅适用于第一个重定向,但如果我在第一页返回/redirect/history.push(),然后尝试像以前一样进行相同的重定向,它似乎刷新了 DOM/页面,但我被困在那里。 this.props.history.push('/something') 是唯一对我有用的东西 我也是,只能使用 withRouter 和 this.props.history.push 谢谢兄弟【参考方案5】:

&lt;Redirect /&gt; 不应包含在 &lt;Switch&gt;&lt;/Switch&gt; 标记内。

【讨论】:

大声笑,在这个线程上所有过度设计的解决方案中,这是唯一对我有用的,而且它是单行的。 试过了。对我没有帮助。 这解决了我的问题!将 放在 之外后,组件会正确呈现。谢谢!【参考方案6】:

你可以这样尝试:

首先:像这样将“withRouter”导入组件:

import  withRouter  from "react-router-dom";

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

export default withRouter(VerifyCode);

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

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

祝你好运

【讨论】:

【参考方案7】:
  const App = (history) =>

  return history.push('/location')  

【讨论】:

【参考方案8】:

添加“精确”以重定向?

例子:

<Switch>
   <Route exact path="/">
      <Redirect to="/home" />
   </Route>
<Switch>

【讨论】:

【参考方案9】:

我用 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>
      );
    

【讨论】:

以上是关于反应路由器 v4 重定向不起作用的主要内容,如果未能解决你的问题,请参考以下文章

反应路由器私有路由/重定向不起作用

反应路由器重定向在私有路由中不起作用

反应重定向到另一个页面不起作用[重复]

如何将上下文 api 与反应路由器 v4 一起使用?

Angular ui 路由器 - 重定向根本不起作用

反应路由重定向 onClick