Reactjs 如何在React Router v4中操作历史记录?

Reactjs 如何在React Router v4中操作历史记录?,reactjs,redux,react-router,react-redux,react-router-redux,Reactjs,Redux,React Router,React Redux,React Router Redux,我正在使用: 反应,重演,反应路由器,流星 以下情况: import { history } from '/imports/client/store'; .... export default class EventCreationModal extends Component { constructor() { super(); this.handleSelect = this.handleSelect.bind(this); this.

我正在使用:

反应,重演,反应路由器,流星

以下情况:

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>
    )
}
我有一个带有两个选项卡的模式,根据所选选项卡,内容区域中将显示不同的选择列表,选择一个选择将给出一个子选择列表(所有都在模式中)

期望的行为:

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>
    )
}
我希望用户能够使用浏览器的“后退”按钮“撤消”单击其中一个选项卡或选择一个选项

迄今为止我所做的尝试都没有成功:

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>
    )
}
  • 使用withRouter HOC包装我的组件,以便访问历史记录。然后我将使用history.push(currentUrl,{selectedTab:selection}) ->问题:推送的状态未存储在此历史位置对象上,但仅存储在与我的rootcomponent关联的历史对象的状态中(位于树的更高位置)

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

  • 有什么想法吗


    干杯

    我改进了第二种方法,现在它开始工作了。将历史导入到我的模块(作为一个局部变量)中,从而完全绕过react-tree、redux-store和react-router,这仍然让人感觉不舒服。 然而,它正在工作,到目前为止没有引起任何错误。所以我们走吧

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

    import createHistory from 'history/createBrowserHistory';
    ...
    const history = createHistory();
    ...
    export { history , store }
    
    正如你所看到的,这是历史。然后,我在:
    routes.js模块中将所述历史记录提供给我的路由器(在我的例子中是ConnectedRouter,因为我正在使用react Router redux)

    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>
        );
    };
    
    从'/imports/client/store'导入{store,history};
    const MyStoreRouter=()=>{
    返回(
    );
    };
    
    现在来看古怪的部分。我将历史导入到一个显示组件中,并使用它设置一个侦听器(以在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>
        )
    }
    
    从'/imports/client/store'导入{history};
    ....
    导出默认类EventCreationModel扩展组件{
    构造函数(){
    超级();
    this.handleSelect=this.handleSelect.bind(this);
    此.state={
    selectedCategory:(history.location.state&&history.location.state.category)?history.location.state.category:'sports',
    };
    历史。聆听((位置、动作)=>{
    这是我的国家({
    selectedCategory:(history.location.state&&history.location.state.category)?history.location.state.category:'sports',
    })
    }); 
    }
    handleSelect(键){
    history.push(“/Home”,{'category':key})
    }
    渲染(){
    返回(
    )
    }
    
    您可以采取的另一种方法是将查询参数与React router一起使用。在您的组件中,根据查询参数更改选项卡。由于url发生了更改,您应该获得您想要的默认行为。

    我有一个项目几乎完全符合这种情况。不同之处在于,它不是处于模式中,而是将其保存在我的标题中。以下是我所做的:

    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);
    
    import React,{Component}来自'React';
    从“react router dom”导入{Link,withRouter};
    类头扩展组件{
    render(){
    返回(
    
    • 统计数据
    • {Meteor.userId()&&
    • 帐户设置
    • }
    ); } } 使用路由器导出默认值(标题);
    react路由器dom…
    是允许这种情况发生的操作项


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

    我想这可能会起作用,也考虑了查询参数,但由于有人可能会复制url并期望达到相同的打开模式,所以我一直在使用它们(他不会这样做)。为模态打开或关闭创建一个查询参数?如果其
    true
    pop the modal,则将其打开?我使用redux打开模态。不完全相同,请进一步检查我给自己的答案。在我看来,您将转到一个新路径,这是我不想做的。我不想更改URL。