How to provide a history instance to a saga?

本小妞迷上赌 提交于 2019-12-06 02:51:01

问题


I would like to redirect to a new page after successful login. The routes (V4) are used like this:

import { browserHistory } from '....browser_history_signleton';
...

class App extends Component {
  render() {
    const { authentication: { isSignedIn } } = this.props;
    return (
      <ConnectedRouter history={browserHistory}>
        <div>
          <Header/>
          <Route exact path="/" component={Home}/>
          <PrivateRoute isAuthorized={isSignedIn} path="/page1" component={PageOne}/>
          <PrivateRoute isAuthorized={isSignedIn} path="/page2" component={PageTwo}/>
        </div>
      </ConnectedRouter>
    );
  }
}

The saga looks like:

import { browserHistory } from '....browser_history_signleton';

export function* loginSaga() {
  while (true) { // eslint-disable-line no-constant-condition
    try {
      const payload = yield take(LOGIN_SUBMIT);
      const raceResult = yield race({
        signin: call(loginRequest, payload),
        logout: take('LOGOUT')
      });
      if (raceResult.signin) {
        const { data }  = raceResult.signin;
        yield put(loginRequestSucceeded(data));
        const redirectUrl = `.....based on location.state.from.pathname`
        browserHistory.push(rediretUrl);
        ...

My main issue is how to share browserHistory. createHistory from history module is not a signleton, so I had to add:

// browser_history_signleton.js
import createHistory from 'history/createBrowserHistory';

export const browserHistory = createHistory();

What is the most efficient way to provide a history instance to a saga?


回答1:


As you pointed out, making history directly available as a singleton is one option. Another similar (if not controversial) approach is to add history to the redux state. So in your saga, you'd use a select effect to get the history instance.

Both approaches effectively treat history as singletons, but by storing it into the redux state, you can mock the history object a bit easier in unit tests. What I mean by easier is that you can employ the same technique to mock the history object as mocking any other object in the redux state.

Also, you would presumably instantiate the history object along with other initial state so your logic to initialize history wouldn't be a one off exception as to how application state is initialized.



来源:https://stackoverflow.com/questions/42893161/how-to-provide-a-history-instance-to-a-saga

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!