Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to pass redux state to sub routes?

I have a hard time understanding how to use redux together with react-router.

index.js

[...]

// Map Redux state to component props
function mapStateToProps(state)  {
  return {
    cards: state.cards
  };
}

// Connected Component:
let ReduxApp = connect(mapStateToProps)(App);

const routes = <Route component={ReduxApp}>
  <Route path="/" component={Start}></Route>
  <Route path="/show" component={Show}></Route>
</Route>;

ReactDOM.render(
  <Provider store={store}>
    <Router>{routes}</Router>
  </Provider>,
  document.getElementById('root')
);

App.js

import React, { Component } from 'react';

export default class App extends React.Component {
  render() {
    const { children } = this.props;
    return (
      <div>
      Wrapper
        {children}
      </div>
    );
  }
}

Show.js

import React, { Component } from 'react';

export default class Show extends React.Component {
  constructor(props) {
    super(props);
  }

  render() {
    return (
      <ul>
        {this.props.cards.map(card => 
          <li>{card}</li>
        )}
      </ul>
    );
  }
}

This throws

Uncaught TypeError: Cannot read property 'map' of undefined

The only solution I've found is to use this instead of {children}:

{this.props.children &&
 React.cloneElement(this.props.children, { ...this.props })}

Is this really the proper way to do it?

like image 301
user2906759 Avatar asked Oct 20 '15 11:10

user2906759


People also ask

How do you pass data from one component to another component using Redux?

You could use a state management tool like Redux for example. After fetching the data with Axios save it to the Redux store. Doing that makes the data available to be used by another components.

Can Redux state be manipulated?

Yes it can be easily manipulated.

What is mapStateToProps and mapDispatchToProps?

The mapStateToProps and mapDispatchToProps deals with your Redux store's state and dispatch , respectively. state and dispatch will be supplied to your mapStateToProps or mapDispatchToProps functions as the first argument.


1 Answers

Use react-redux

In order to inject any state or action creators into the props of a React component you can use connect from react-redux which is the official React binding for Redux.

It is worth checking out the documentation for connect here.

As an example based on what is specified in the question you would do something like this:

import React, { Component } from 'react';
// import required function from react-redux
import { connect } from 'react-redux';

// do not export this class yet
class Show extends React.Component {
  // no need to define constructor as it does nothing different from super class

  render() {
    return (
      <ul>
        {this.props.cards.map(card => 
          <li>{card}</li>
        )}
      </ul>
    );
  }
}

// export connect-ed Show Component and inject state.cards into its props.
export default connect(state => ({ cards: state.cards }))(Show);

In order for this to work though you have to wrap your root component, or router with a Provider from react-redux (this is already present in your sample above). But for clarity:

import React from 'react';
import ReactDOM from 'react-dom';
import { Router, Route } from 'react-router';

import { createStore } from 'redux';
import { Provider } from 'react-redux';

import reducers from './some/path/to/reducers';

const store = createStore(reducers);

const routes = <Route component={ReduxApp}>
  <Route path="/" component={Start}></Route>
  <Route path="/show" component={Show}></Route>
</Route>;

ReactDOM.render(
  // Either wrap your routing, or your root component with the Provider so that calls to connect have access to your application's state
  <Provider store={store}>
    <Router>{routes}</Router>
  </Provider>,
  document.getElementById('root')
);

If any components do not require injection of any state, or action creators then you can just export a "dumb" React component and none of the state of your app will be exposed to the component when rendered.

like image 97
GordyD Avatar answered Oct 02 '22 07:10

GordyD