2017-01-15 110 views
0

我正在開發我的第一個'大'react-redux應用程序。我試圖映射組件之間的react-redux狀態,但似乎我錯過了一些東西。react-redux存儲組件映射問題

除了一件事情之外,一切都像魅力一樣:我的菜單反應路線導航工作正常,我的組件被渲染,按鈕onClick事件沒問題,我的其餘api被調用,並且返回帶有正確的json數據的http 200它被添加到redux商店(我猜)。

唯一不起作用的是this.state在TableRenderer.js中爲null。

我所得到的是有關Redux的狀態映射錯誤:

Uncaught TypeError: Cannot read property 'json' of null

App.js(主類)

const store = createStore(
    combineReducers({ 
     ...reducers, 
     routing: routerReducer 
    }), 
    applyMiddleware(thunk) 
) 

const history = syncHistoryWithStore(browserHistory, store) 

ReactDom.render(
    <Provider store={store}> 
     <Router history={history}> 
      <Route path='/' component={MainLayout}> 
       <Route path='about' component={About}/> 

       <Route path="list"> 
        <Route path="people" component={PeopleList}/> 
       </Route> 

       <Route path='*' component={NotFound}/> 
      </Route> 
     </Router> 
    </Provider>, 
    document.getElementById('root') 
); 

PeopleList.js(我的主要成分)

export default class PeopleList extends React.Component { 
    render() { 
     return (
      <TableRenderer title='My 1st people list' /> 
     ); 
    } 
} 

個TableRenderer.js(從終極版儲存讀取數據並呈現)

export default class TableRenderer extends React.Component { 
    render() { 
    return (
     <div> 
     <p style={STYLE.title}>{this.props.title}</p> 
     <ActionBar /> 
     <table style={STYLE.table}> 
      <thead style={STYLE.tableHead}> 
      <tr> 
       <th style={STYLE.td}>id</th> 
       <th style={STYLE.td}>field 1</th> 
       <th style={STYLE.td}>field 2</th> 
       <th style={STYLE.td}>field 3</th> 
      </tr> 
      </thead> 
      <tbody style={STYLE.tableBody}> 
      {this.state.json.map(row => { 
       return <RowRenderer key={row.id} row={row} /> 
      })} 
      </tbody> 
     </table> 
     <ActionBar /> 
     </div> 
    ); 
    } 
} 

ActionBar.js(其持有的按鈕和調度動作)

class ActionBar extends React.Component { 
    render() { 
     return (
      <div style={STYLE.actionBar}> 
       <Button bsSize="xsmall" 
         onClick={() => this.props.doRefresh()}> 
        Refresh 
       </Button> 
       <Button bsSize="xsmall">Clear all from database</Button> 
      </div> 
     ); 
    } 
} 

const mapStateToProps = (state) => { 
    return { 
     json: state.json 
    }; 
}; 

const mapDispatchToProps = (dispatch) => { 
    return { 
     doRefresh:() => dispatch(fetchData()) 
    }; 
}; 

export default connect(mapStateToProps, mapDispatchToProps)(ActionBar) 

TableAction.js(我的行動類)

const loadDataAction = (json) => { 
    return { 
     type: ActionType.GET_DATA, 
     json: json 
    } 
}; 

export function fetchData() { 
    return (dispatch) => { 
     dispatch(loadDataAction('')); 

     axios({ 
      baseURL: UrlConstant.SERVICE_ROOT_URL, 
      url: 'list/people', 
      method: 'get' 
     }) 
      .then((response) => { 
       if (response.status == 200) { 
        dispatch(loadDataAction(response.data)); 
       } 
      }) 
      .catch((error) => { 
       if (error.response) { 
        dispatch(loadDataAction('')); 
       } 
      }); 
    } 
} 

個Reducers.js

const initialState = { 
    json: '' 
}; 

export default (state = initialState, action) => { 
    return Object.assign({}, state, { 
     json: action.json 
    }); 
} 

UPDATE: 感謝您最大Sindwani的幫助,這個問題就解決了。有很多事情要解決。

App.js(主類) 我店的定義是不正確的

const store = createStore(
    combineReducers({ 
     response: reducer, 
     routing: routerReducer 
    }), 
    applyMiddleware(thunk) 
) 

TableRenderer.js

{this.props.json} needs to be used instead of {this.state.json} 

一個連接的工作人員被從這個類失蹤。它界定終極版存儲和類區域道具之間的數據(如果我是正確的):

class TableRenderer extends React.Component { 
    render() { 
     return (
      <div> 
       ... 
      </div> 
     ); 
    } 
} 

const mapStateToProps = (state) => { 
    return { 
     json: state.response.json 
    }; 
}; 

export default connect(mapStateToProps)(TableRender) 

減速。js

我的reducer也是錯誤的,因爲沒有switch語句,在初始階段store通過redux以錯誤的方式初始化。而json的類型需要是數組,因爲它包含乘法項。

const initialState = { 
    json: [] 
}; 

export default (state = initialState, action) => { 
    switch (action.type) { 
     case ActionType.GET_DATA: 
      return Object.assign({}, state, { 
       json: action.json 
      }); 
     default: 
      return state; 
    } 
}; 

export default reduces; 

就是這樣:)

回答

0

的錯誤似乎涉及到的事實,state將是無效的(因爲沒有定義初始本地狀態)。 Redux旨在提供來自提供者組件的單向數據流。您需要傳遞道具或從組件連接(儘管建議您僅連接頂層組件,以避免丟失數據來源的位置)。任何時候reducer都會返回一個新的/更新的狀態,提供者再次將道具傳遞給它的子項,並使它們重新渲染。嘗試連接TableRenderer。像這樣的東西應該工作:

class TableRenderer extends React.Component { 
    render() { 
    return (
     <div> 
     <p style={STYLE.title}>{this.props.title}</p> 
     <ActionBar /> 
     <table style={STYLE.table}> 
      <thead style={STYLE.tableHead}> 
      <tr> 
       <th style={STYLE.td}>id</th> 
       <th style={STYLE.td}>field 1</th> 
       <th style={STYLE.td}>field 2</th> 
       <th style={STYLE.td}>field 3</th> 
      </tr> 
      </thead> 
      <tbody style={STYLE.tableBody}> 
      {this.props.json.map(row => { 
       return <RowRenderer key={row.id} row={row} /> 
      })} 
      </tbody> 
     </table> 
     <ActionBar /> 
     </div> 
    ); 
    } 
} 

const mapStateToProps = (state) => { 
    return { 
     json: state.json 
    }; 
}; 

export default connect(mapStateToProps)(TableRenderer); 

注意,連接和映射的狀態之後,狀態存在如部分道具。另外請注意,如果您使用map並將初始狀態保持爲空數組,則需要將json(如果尚未)更改爲數組。

此外,請檢查以確保您的減速器已包含在內。看起來你並沒有將關鍵字與json reducer相關聯(假設routerReducer來自https://github.com/reactjs/react-router-redux)。嘗試這樣 - https://jsfiddle.net/msindwan/bgto9c8c/

+0

嗨,謝謝你的答覆。我已將連接人員添加到TableRendeer類,並將this.state.json更改爲this.props.json。現在我有一個props.json是null錯誤:Chrome:未捕獲TypeError:無法讀取undefined的屬性'map',Firefox:TypeError:this.props.json未定義 – zappee

+0

映射到道具時的狀態輸出是什麼?你可以在mapStateToProps中添加一個console.log(狀態)嗎? –

+0

此外,我已更新我的示例以修復一些小錯誤 –