[英]How to pass redux state to sub routes?
I have a hard time understanding how to use redux together with react-router. 我很难理解如何将redux与react-router一起使用。
index.js 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 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 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 未捕获的TypeError:无法读取未定义的属性“map”
The only solution I've found is to use this instead of {children}: 我发现的唯一解决方案是使用它而不是{children}:
{this.props.children &&
React.cloneElement(this.props.children, { ...this.props })}
Is this really the proper way to do it? 这真的是正确的方法吗?
Use react-redux 使用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. 为了将任何状态或动作创建者注入到React组件的props
,您可以使用来自react-redux
connect
,这是Redux的官方React绑定。
It is worth checking out the documentation for connect
here . 有必要在这里查看connect
文档。
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). 为了实现这一点,您必须使用react-redux
的Provider
包装您的根组件或路由器(这已在上面的示例中提供)。 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. 如果任何组件不需要注入任何状态或动作创建者,那么您只需导出一个“哑”的React组件,并且在渲染时,您的应用程序状态都不会暴露给组件。
I solved it by explicitly mapping the state with connect in every component: 我通过在每个组件中使用connect显式映射状态来解决它:
export default connect(function selector(state) {
return {
cards: state.cards
};
})(Show);
This way I can decide what properties of the state the component should have access to as well, polluting the props less. 通过这种方式,我可以决定组件应该访问的状态的哪些属性,更少地污染道具。 Not sure if this is best practice though. 不确定这是否是最好的做法。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.