【问题标题】:react-router: change route from component or storereact-router:从组件或存储更改路由
【发布时间】: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 */);

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

【问题讨论】:

    标签: reactjs react-router reactjs-flux


    【解决方案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。不知道是什么原因,想了解一下……

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2019-06-04
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-04-28
      • 2018-08-06
      • 1970-01-01
      相关资源
      最近更新 更多