React Router v4从MobX存储操作导航?

时间:2017-07-28 16:00:22

标签: reactjs react-router react-router-v4 mobx

我正在尝试让路由器v4从store中的操作进行导航,而不会明确地将history道具传递给需要在某些逻辑运行后导航的每个商店操作。

我正在寻找这样的工作:

import { NavigationStore } from 'navigation-store';

class ContactStore {
  @action contactForm(name, message){
    // Some logic runs here

    // Then navigate back or success

    // Go back
    NavigationStore.goBack();

    // Or Navigate to Route
    NavigationStore.push('/success'); 
  }
}

当然NavigationStore不存在(我不知道从React路由器中放入什么来使其工作),但我想导入一个mobx导航存储我可以使用与react-router

相同的api在应用程序(组件或商店)中的任何位置导航和导航

怎么做?

更新

RR4没有为我们提供从商店行为导航的方法。我正在尝试使用RR4导航就像上面一样。我只需知道navigation-store应包含哪些内容,以便我可以:

  1. import { NavigationStore } from 'navigation-store';任何地方(组件/商店),也是历史记录,能够从任何地方导航。
  2. NavigationStore.RR4Method(RR4MethodParam?);其中RR4Method将是可用的RR4导航选项,例如push,goBack等。(这就是应该如何进行导航)
  3. 更新2:

    因此,网址现在从NavigationStore.push('/success');更新,但不会发生网页刷新。

    以下是navigation-store.js

    import { observable, action } from 'mobx'
    import autobind from 'autobind-decorator'
    import createBrowserHistory from 'history/createBrowserHistory'
    
    class NavigationStore {
      @observable location = null;
      history = createBrowserHistory();
    
      @autobind push(location) {
        this.history.push(location);
      }
      @autobind replace(location) {
        this.history.replace(location);
      }
      @autobind go(n) {
        this.history.go(n);
      }
      @autobind goBack() {
        this.history.goBack();
      }
      @autobind goForward() {
        this.history.goForward();
      }
    }
    
    const navigationStore = new NavigationStore();
    
    export default navigationStore;
    

    以下是app.js

    import React from 'react'
    import { Provider } from 'mobx-react'
    import { BrowserRouter as Router, Route } from 'react-router-dom'
    import Contact from 'screens/Contact'
    import Success from 'screens/Success'
    
    export default class App extends React.Component {
      render() {
        return (
          <div>
            <Provider>
              <Router>
                <div>
                  <Route path='/contact' component={Contact} />
                  <Route path='/success' component={Success} />
                </div>
              </Router>
            </Provider>
          </div>
        );
      }
    }
    

    网址更改为/success后,网页没有任何反应,而不是在这种情况下加载匹配的组件Success。仍然困在这里..

    更新3(解决方案):

    This helped我把它作为其他人的参考,因为这对我来说非常令人沮丧。

    app.js我必须改变:

    import { BrowserRouter as Router, Route } from 'react-router-dom'
    <Router>
    

    import { Route } from 'react-router-dom'
    import { Router } from 'react-router'
    import navigationStore from 'stores/navigation-store'
    <Router history={navigationStore.history}>
    

    我希望这有助于其他人:)

1 个答案:

答案 0 :(得分:5)

您始终可以将商店用作另一个商店的构造函数参数。然后,您就可以正确使用NavigationStore实例了。

因此,在初始化商店的地方,您可以:

const navigationStore = new NavigationStore(); 
const contactStore = new ContactStore(navigationStore)
const stores = {
    navigationStore, 
    contactStore
}

然后您的联系商店变为:

class ContactStore {
  _navigationStore; 
  constructor(navigationStore) {
    this._navigationStore = navigationStore;
  }
  @action contactForm(name, message){
    // Some logic runs here

    // Then navigate back or success

    // Go back
    this._navigationStore.goBack();

    // Or Navigate to Route
    this._navigationStore.push('/success'); 
  }
}

修改

您还可以use a singleton导出商店实例,然后通过在任何模块中导入它来使用它。所以你可以这样:

navigationStore.js

class NavigationStore() {
    goBack() {...}; 
    push(target) {...};
}
const navigationStore = new NavigationStore();
// The trick here is to export the instance of the class, not the class itself
// So, all other modules use the same instance.  
export default navigationStore;

contactStore.js

import navigationStore from 'navigation-store';
// We import the naviationStore instance here

class ContactStore {
  @action contactForm(name, message){
    // Some logic runs here

    // Then navigate back or success

    // Go back
    navigationStore.goBack();

    // Or Navigate to Route
    navigationStore.push('/success'); 
  }
}

App.js :在哪里初始化mobx提供商的商店:

import navigationStore from './navigationStore'; 
// We import the same instance here, to still have it in the provider.
// Not necessary if you don't want to inject it. 

const stores = {
    navigationStore, 
    contactStore: new ContactStore();
}