【问题标题】:How to manipulate history in React Router v4?如何在 React Router v4 中操作历史记录?
【发布时间】:2017-12-08 11:11:04
【问题描述】:

我正在使用:

React、Redux、React-Router、Meteor

以下情况:

我有一个带有两个选项卡的模式,根据选择的选项卡,内容区域中将显示不同的选择列表,选择一个选项将给出子选择列表(全部在模式中)。

期望的行为:

我希望用户能够使用浏览器的后退按钮来“撤消”单击其中一个选项卡或选择一个选项。

到目前为止我尝试过的事情都没有成功:

  1. 使用 withRouter HOC 来包装我的组件,以便我可以访问历史记录。然后我会使用 history.push(currentUrl,{selectedTab:selection}) -> 问题:推送的状态没有存储在这个历史位置对象中,而只是存储在与我的根组件关联的历史对象的状态中(在树的更上方)

  2. (到目前为止更有希望)只需将我使用 createHistory 创建的历史记录导入另一个模块,然后在构建时将其放入组件状态。 然后我将使用this.state.history.push(currentUrl,{selectedTab:selection}) 访问推送方法,它工作正常,我可以在this.state.history.location.state.selectedTab 下找到推送状态。但是,使用浏览器的后退按钮不会导致重新呈现,因此选择将保持不变。

有什么想法吗?

干杯

【问题讨论】:

    标签: reactjs redux react-router react-redux react-router-redux


    【解决方案1】:

    我改进了第二种方法,现在它正在工作。将历史记录导入我的模块(作为局部变量)仍然感觉很笨拙,因此完全绕过了反应树、redux 存储和反应路由器。 但是,它正在工作并且到目前为止没有引起任何错误。所以我们开始...

    我将我的历史对象实例化在:
    store.js 模块

    import createHistory from 'history/createBrowserHistory';
    ...
    const history = createHistory();
    ...
    export { history , store }
    

    你可以看到出口历史。然后,我将上述历史记录提供给我的路由器(在我的情况下为 ConnectedRouter,因为我使用的是 react-router-redux):
    routes.js 模块

    import { store , history } from '/imports/client/store';
    
    const MyStoreRouter = () => {
        return (
            <Provider store={store}>
                <ConnectedRouter history={ history }>
                    <div>
                        <Switch>
                            <Route exact path="/" component={Landing}/>
                            <Route path="/" component={MainApp}/>
                        </Switch>
                    </div>
                </ConnectedRouter>
            </Provider>
        );
    };
    

    现在是古怪的部分。我将历史记录导入到显示组件中,并使用它来设置侦听器(以声明 history.location 中的更改)并相应地更改状态:
    DisplayComponent.js 模块:

    import { history } from '/imports/client/store';
    ....
    export default class EventCreationModal extends Component {
        constructor() {
            super();
            this.handleSelect = this.handleSelect.bind(this);
            this.state = {
                selectedCategory: (history.location.state && history.location.state.category) ? history.location.state.category : 'sports',
            };
            history.listen((location,action) => {
                this.setState({
                    selectedCategory: (history.location.state && history.location.state.category) ? history.location.state.category : 'sports',
                })
            }); 
        }
    
        handleSelect(key) {
            history.push("/Home",{'category':key})
        }
    
    render () {
        return (
            <Tabs activeKey={this.state.selectedCategory} onSelect={this.handleSelect} id="SportOrSocialSelector">
                <Tab eventKey={'sports} .../>
                <Tab eventKey={'social} .../>
            </Tabs>
        )
    }
    

    【讨论】:

      【解决方案2】:

      您可以采取的另一种方法是将查询参数与 React 路由器一起使用。并在您的组件中根据查询参数更改选项卡。由于 url 改变了,你应该得到你正在寻找的默认行为。

      【讨论】:

      • 我想这可能可行,也考虑过查询参数,但因为有人可能会复制 URL 并可能期望到达相同的打开模式(他不会)而阻止使用它们.
      • 为模式打开或关闭创建一个查询参数?如果 true 弹出模态框,则打开它?
      • 我使用redux打开modal。
      【解决方案3】:

      我有一个项目几乎就是这种情况。不同之处在于,它不是在模式中,而是在我的标题中。这是我所做的:

      import React, { Component } from 'react';
      import { Link, withRouter } from 'react-router-dom';
      
      class Header extends Component {
        render() {
          return (
            <ul className="tabs tabs-fixed-width z-depth-1">
              <li className="tab">
                <Link id="books-tab" to={'/books'}>Books</Link>
              </li>
              <li className="tab">
                <Link id="stats-tab" to={'/stats'}>Stats</Link>
              </li>
              {Meteor.userId() &&
                <li className="tab">
                  <Link id="user-tab" to={'/user'}>Account Settings</Link>
                </li>}
            </ul>
          );
        }
      }
      
      export default withRouter(Header);
      

      react-router-dom &lt;Link&gt;... 是允许这种情况发生的有效项目。

      然后,当我单击选项卡时,每个链接都会转到指定的 url 并将其保存在历史记录中,这样我就可以返回到上一个选项卡。

      【讨论】:

      • 不太一样,请查看下面我给自己的答案。在我看来,你会走一条新的路线,我不想这样做。我不想更改 URL。
      猜你喜欢
      • 2017-07-29
      • 2017-07-30
      • 1970-01-01
      • 1970-01-01
      • 2017-12-14
      • 2020-10-16
      相关资源
      最近更新 更多