2015-10-20 76 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') 
); 

如果任何組件不需要注射任何國家或動作的創造者,那麼你可以只導出一個「啞」響應成分,沒有您的應用程序的狀態將被暴露在組件當呈現。

相關問題