当路由器收到状态时,React 路由器 redux 滞后一个历史步骤 [英] React router redux lags one history step behing when router receives state

查看:43
本文介绍了当路由器收到状态时,React 路由器 redux 滞后一个历史步骤的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

这是一个带有完整代码的存储库,用于演示问题-https://github.com/Misiur/ReactRouterReduxBug

在线 - https://codesandbox.io/s/v88B5LG0

看看这段代码

class Main 扩展组件 {componentWillReceiveProps(nextProps) {if (this.props.match.params.page !== nextProps.match.params.page) {console.log(`页面更改为 ${nextProps.match.params.page}`);} 别的 {console.log('页面没有改变');console.log(newProps.location.pathname);console.log(newProps.history.location.pathname);}}使成为() {const page = this.props.match.params.page;返回 (<div><strong>当前页面是{page}</strong><br/><Link to="/1">第 1 页</Link><br/><Link to="/2">第 2 页</Link><br/><Link to="/3">第 3 页</Link><br/><Link to="/4">第 4 页</Link><br/><Link to="/5">第 5 页</Link>

);}}const RawRouting = (props) =>{//用 this.props.state 做一些事情//console.log(props);返回 (<路由路径="/:page(\d+)?"组件={主}/>);};const Routing = connect(state => ({ state }))(RawRouting);const App = () =>{返回 (<提供者商店={商店}><ConnectedRouter history={history}><路由/></ConnectedRouter></提供者>);};

我们有 App 为商店和路由器搭建脚手架,Routing 定义路由并且connect连接到状态Main 组件显示页面和页面链接.

当您点击链接时,一切正常.但是,当您按下浏览器的后退按钮时,第一次 url 更改但路由参数没有更改,因为 newProps.location.pathnamenewProps.history.location.pathname 落后一个历史步骤>.

我已经深入挖掘,找出导致它的原因,但没有找到原因:Routing 上的 connect.当它被移除时,后退按钮正常工作.这不是解决方案,因为我需要那里的状态.

所以:

  1. 如何让后退/前进按钮在不删除我的状态映射的情况下工作?
  2. 为什么会是这样?

解决方案

答案是将其包装在 withRouter 中.请参阅 https://github.com/ReactTraining/react-router/blob/master/packages/react-router/docs/guides/redux.md#blocked-updates

Here's a repo with full code demonstrating the problem - https://github.com/Misiur/ReactRouterReduxBug

Online - https://codesandbox.io/s/v88B5LG0

Take a look at this code

class Main extends Component {
  componentWillReceiveProps(nextProps) {
    if (this.props.match.params.page !== nextProps.match.params.page) {
      console.log(`Page changed to ${nextProps.match.params.page}`);
    } else {
      console.log('Page did not change');
      console.log(newProps.location.pathname);
      console.log(newProps.history.location.pathname);
    }
  }

  render() {
    const page = this.props.match.params.page;

    return (
      <div>
        <strong>Current page is {page}</strong><br />
        <Link to="/1">Page 1</Link><br />
        <Link to="/2">Page 2</Link><br />
        <Link to="/3">Page 3</Link><br />
        <Link to="/4">Page 4</Link><br />
        <Link to="/5">Page 5</Link>
      </div>
    );
  }
}

const RawRouting = (props) => {
  // Do something with this.props.state
  // console.log(props);

  return (
    <Route path="/:page(\d+)?" component={Main} />
  );
};

const Routing = connect(state => ({ state }))(RawRouting);

const App = () => {
  return (
    <Provider store={store}>
      <ConnectedRouter history={history}>
        <Routing />
      </ConnectedRouter>
    </Provider>
  );
};

We have App which scaffolds the store and router, Routing which defines routes and is connected to the state, and Main component displaying page and links to pages.

When you click on links, all works fine. However when you push browser's back button, first time url changes but the route parameter does not, because newProps.location.pathname is one history step behind newProps.history.location.pathname.

I've dug deep enough to find out what causes it, but not why: the connect on our Routing. When it is removed, back button works correctly. That's not the solution as I need the state there.

So:

  1. How to make back/forward button work without removing my state mapping?
  2. Why is it the way it is?

解决方案

The answer is to wrap it in withRouter. See https://github.com/ReactTraining/react-router/blob/master/packages/react-router/docs/guides/redux.md#blocked-updates

这篇关于当路由器收到状态时,React 路由器 redux 滞后一个历史步骤的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆