Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do I get a hold of the store/dispatch in React-Router onEnter?

I'm not using Redux-Router (maybe I have to?) but my router is wrapped by Provider and the store is being passed to that.

I'd like to read state and dispatch in the onEnter handler.

like image 681
kjs3 Avatar asked Nov 11 '15 02:11

kjs3


2 Answers

I just wrapped my routes in a function that returns them.

This allows you to pass the redux store as an argument

Any onEnter/onExit functions are also defined in there so they have access to that store argument and can dispatch() stuff.

import React from 'react'
import { IndexRoute, Route } from 'react-router'

import App from './components/app'
import FourOhFour from './components/pages/404'
import Home from './components/home'
import LogIn from './components/account/log_in'
import ResetPassword from './components/account/reset_password'
import SignUp from './components/account/sign_up'

export function getRoutes (store) {
  function doSomething (thing) {
    store.dispatch(addToDoActionCreator(thing))
  }

  function authenticate (nextState, replaceState) {
    const { currentUser } = store.getState();

    if ( !currentUser ) {
      replaceState(null, '/log-in');
    }
  }

  return (
    <Route path='/' component={App}>
      <IndexRoute component={Home} onEnter={(nextState, replaceState)=>{doSomething('get coffee')}} />

      <Route path='log-in' component={LogIn} onEnter={authenticate} />
      <Route path='sign-up' component={SignUp} />
      <Route path='reset-password' component={ResetPassword} />

      <Route path="*" component={FourOhFour}/>
    </Route>
  );
}

On the server side (express.js for me) I establish a redux store fairly early with middleware. Something like this.

server.use((req, res, next) => {
  const createStoreWithMiddleware = applyMiddleware(
    thunkMiddleware
  )(createStore);
  res.store = createStoreWithMiddleware(rootReducer);

  next();
}

So now the store is attached to the response object and can be used by other middleware/routes. They can get state (res.store.getState()) and dispatch to update state.

like image 80
kjs3 Avatar answered Sep 28 '22 10:09

kjs3


Just create your redux store in an seperate file and require it when it's needed.

// store.js

import { createStore } from 'redux'
import todoApp from './reducers'
  
export default createStore(todoApp);

// the file where you define your routes and onEnter

import { render } from 'react-dom';
import { Router, Route } from 'react-router';
import store, { dispatch } from './store.js';

function enterHandler(){
  dispatch(allTheGoodStuff);
}

render(
  <Router>
    <Route onEnter={ enterHandler } ...
)
like image 44
Burak Can Avatar answered Sep 28 '22 08:09

Burak Can