简体   繁体   中英

Access redux store from redux-simple-router children

I'm trying to figure out how to access the redux store from within route so I can dispatch actions from within the route.

Here's what my top level Component looks like:

class App extends Component {
  render() {
    return (
      <div>
         { children }
      </div>
    );
  }
}

My redux-simple-router code looks like:

render(
  <Provider store={store}>
    <Router history={history}>
      <Route path="/" component={App}>
        <IndexRoute component={ Home } />
        <Route path="/example" component={ ExampleRoute } />
      </Route>
    </Router>
  </Provider>,
  rootElement
)

If I dump props from within the ExampleRoute component, I don't have access to the store. Any help appreciated!

You should use connect from react-redux to get dispatch and current state from the store. It is outlined in the redux docs here: http://rackt.org/redux/docs/basics/UsageWithReact.html

Here is your Example component:

//...
import { connect } from 'react-redux'
//...

export class Example extends Component {
    render () {
        const { dispatch, thingName } = this.props
        return (
            <button onClick={ () => {
                dispatch(myAwesomeActionCreator())
            }}>{ thingName }</button>
        );
    }
}

export default connect(state => state)(Example)

Some good examples of how to use connect can be found in the react-redux docs: https://github.com/rackt/react-redux/blob/master/docs/api.md#examples

I was able to get this working with "Monkeypatch" middleware, but there's got to be a better way.

First I created a function to monkeypatch the children variable. This function takes the child, the dispatch and the store as arguments, and returns an updated children variable with keys for the store and dispatch:

function routeStoreMiddleware (children, dispatch, store) {
  return {
    ...children,
    props: {
      ...children.props,
      dispatch: dispatch,
      store: store
    }
  }
}

Then I simply updated the component that already has access to the dispatch and store to consume the middleware function:

class App extends Component {
  render() {
    return (
      <div>
         { routeStoreMiddleware(children, dispatch, store) }
      </div>
    );
  }
}

Since the poorly named routeStoreMiddleware function simply returns an updated children object, it still works.

Now I can dispatch events and display data from within the ExampleRoute component.

import React, { Component } from 'react'; import { myAwesomeActionCreator } from '../actions.js'

export class Example extends Component {
  render () {
    const { dispatch, store } = this.props
    return (
      <button onClick={ () => {
        dispatch(myAwesomeActionCreator())
      }}>{ store.thingName }</button>
    );
  }
}

Yay!

Please note: I've been reading a lot here about how to make middleware properly in redux, but I haven't had time yet to understand it fully. There's a better way than I've done here.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM