javascript - How to pass redux state to sub routes? - Stack Overflow

I have a hard time understanding how to use redux together with react-router.index.js[...] Map Redux

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

index.js

[...]

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

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

const routes = <Route ponent={ReduxApp}>
  <Route path="/" ponent={Start}></Route>
  <Route path="/show" ponent={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?

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

index.js

[...]

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

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

const routes = <Route ponent={ReduxApp}>
  <Route path="/" ponent={Start}></Route>
  <Route path="/show" ponent={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?

Share Improve this question asked Oct 20, 2015 at 11:55 user2906759user2906759 8311 gold badge9 silver badges15 bronze badges 1
  • Does this answer your question? Line 0: Parsing error: Cannot read property 'map' of undefined – Henke Commented Mar 23, 2022 at 14:03
Add a ment  | 

2 Answers 2

Reset to default 3

Use react-redux

In order to inject any state or action creators into the props of a React ponent 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 ponent, 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 ponent={ReduxApp}>
  <Route path="/" ponent={Start}></Route>
  <Route path="/show" ponent={Show}></Route>
</Route>;

ReactDOM.render(
  // Either wrap your routing, or your root ponent 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 ponents do not require injection of any state, or action creators then you can just export a "dumb" React ponent and none of the state of your app will be exposed to the ponent when rendered.

I solved it by explicitly mapping the state with connect in every ponent:

export default connect(function selector(state) {
  return {
    cards: state.cards
  };
})(Show);

This way I can decide what properties of the state the ponent should have access to as well, polluting the props less. Not sure if this is best practice though.

发布者:admin,转转请注明出处:http://www.yc00.com/questions/1744939245a4602220.html

相关推荐

  • javascript - How to pass redux state to sub routes? - Stack Overflow

    I have a hard time understanding how to use redux together with react-router.index.js[...] Map Redux

    1天前
    40

发表回复

评论列表(0条)

  • 暂无评论

联系我们

400-800-8888

在线咨询: QQ交谈

邮件:admin@example.com

工作时间:周一至周五,9:30-18:30,节假日休息

关注微信