react-router:从组件或存储更改路由

Posted

技术标签:

【中文标题】react-router:从组件或存储更改路由【英文标题】:react-router: change route from component or store 【发布时间】:2017-12-24 21:40:56 【问题描述】:

我正在使用 React、Flux 和 react-router (v4) 的捆绑包。 我的目标是实现服务器端验证,并根据验证结果重定向到另一条路由或保持当前状态并显示验证消息。

我的想法遵循这个场景:

1) 组件收集数据并调用操作

2) store 获取数据是否有效的响应,保存结果并发出更改

3) 组件检测变化并收集状态。如果验证成功则重定向到新路由

组件中的部分功能看起来像(用TS编写):

public componentWillUpdate(): void 
    if (this.state.status === ValidationStatus.OK) 
        this.context.router.history.push(/* another route */);
    


public render(): JSX.Element 
    return (
        <div>
            <div className='form-group'>
                <input type='text' ref='Field1' />
                <input type='text' ref='Field2' />
            </div>
            <span onClick= (e) => this.tryToValidate(e) >Go</span>
        </div>
    );


public componentDidMount(): void 
    this.onChange = this._onChange.bind(this);
    MyStore.addChangeListener(this.onChange);


private _onChange() 
    this.setState(
        status: MyStore.getStatus()
    );

但它不能正常工作 - 重定向仅在第二次点击时触发。

我应该如何更改我的代码以使其正常工作?可能从商店或其他地方调用重定向?...

附:路由器的历史以这种方式包含在组件中:

public static contextTypes = 
    router: PropTypes.shape(
        history: PropTypes.shape(
            createHref: PropTypes.func.isRequired,
            push: PropTypes.func.isRequired,
            replace: PropTypes.func.isRequired
        ).isRequired
    ).isRequired

更新:

找到一种可行但看起来很难看的解决方案:

从组件回调传递到存储为有效负载(回调引发context.router.history.push(/* another route */);

如果服务器验证正常,则在商店中执行此回调。

【问题讨论】:

【参考方案1】:

我终于找到了解决方案。只需将其包含到历史记录中即可存储(这只是草稿,不是工作代码):

import * as history from 'history'

class MyDataStore 

    private dataService = new ValidationService();

    constructor() 
        super();
        AppDispatcher.getInstance().register((payload) => 
            let action = payload.action;
            switch (action.actionType) 
                case AppActions.VALIDATE:
                    this.dataService.validate(action.data).then((validationOk) => 
                        if (validationOk) 
                            history.createHashHistory().push(/* another route */);
                         else 
                            this.emitChange(); // stay on current route
                        
                    );

                    break;
                default:
                    return true;
            

            this.emitChange();
        );
    


唯一的缺点是它只适用于 HashRouter 而不是 BrowserRouter。不知道是什么原因,想了解一下……

【讨论】:

以上是关于react-router:从组件或存储更改路由的主要内容,如果未能解决你的问题,请参考以下文章

React-router:一旦安装,永远不要卸载路由上的组件,即使路由更改

无法以编程方式更改 react-router 中的路由

如何使用 react-router 在组件中保存表单的状态

十react-router 4.x的基本配置

反应路由器:链接更改网址但不加载组件

带有 react-router 的 React.js:我的组件是不是应该对 url 的更改做出“反应”,反之亦然?