2017-01-15 73 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

此外,我已更新我的示例以修复一些小错误 –