2015-10-20 78 views
9

我很难理解如何与react-router一起使用redux。如何将redux状态传递给子路径?

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> 
    ); 
    } 
} 

这将引发

Uncaught TypeError: Cannot read property 'map' of undefined

我发现的唯一的解决办法是改为使用{}儿童这个:

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

这真的是这样做的正确方法?

回答

0

我解决了它与连接中的每个组件映射明确的状态:

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

这样我可以决定什么状态的性能组件应该有机会获得为好,污染少的道具。不知道这是否是最佳做法。

+0

我认为你不需要在每个组件中完成它,只需要你的顶层和路由处理程序组件。在你的例子中,Show是一个Route Handler,因此使用connect(这就是所谓的智能或容器组件)总的来说很好。它下面的所有组件(演示组件或哑组件)应该从Smart组件获取它们的状态作为道具。 看看这里:http://redux.js.org/docs/basics/UsageWithReact.html – woolagaroo

+0

可以请你给一些简单的例子,如何正确地做到这一点? – farukg

3

使用反应 - 终极版

为了注入任何国家或行动创成阵营组成的props可以使用connectreact-redux这是官方的反应终极版结合。

值得看看connecthere的文档。

举个例子基于什么是问题的规定,你会做这样的事情:

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); 

为了这个工作,虽然你有来包装你的根组件,或路由器与Providerreact-redux(这已经出现在上面的示例中)。但是为了清楚:

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') 
); 

如果任何组件不需要注射任何国家或动作的创造者,那么你可以只导出一个“哑”响应成分,没有您的应用程序的状态将被暴露在组件当呈现。

相关问题