组件之间的 react-redux 存储映射问题
react-redux store mapping issue between components
我正在开发我的第一个 'big' react-redux 应用程序。我正在尝试在组件之间映射 react-redux 状态,但似乎我错过了一些东西。
除一件事外,一切都像魅力一样:我的带有反应路线导航的菜单工作正常,我的组件已呈现,按钮 onClick 事件正常,我的其余部分 api 被调用,我返回 http 200使用适当的 json 数据添加到 redux 存储(我猜)。
唯一不起作用的是 this.state 在 TableRenderer.js.
中为 null
我得到的错误与 redux 状态映射有关:
Uncaught TypeError: Cannot read property 'json' of null
App.js(主要class)
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(从 redux store 读取数据并渲染)
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(我的动作class)
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
});
}
更新:
感谢 Max Sindwani 的帮助,此问题已解决。有很多事情要解决。
App.js(主要class)
我的商店定义不正确
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 中缺少连接人员。它在 redux store 和 class locale props 之间绑定数据(如果我是正确的):
class TableRenderer extends React.Component {
render() {
return (
<div>
...
</div>
);
}
}
const mapStateToProps = (state) => {
return {
json: state.response.json
};
};
export default connect(mapStateToProps)(TableRender)
Reducers.js
我的 reducer 也是错误的,因为没有 switch 语句,在初始阶段,redux 以错误的方式初始化了 store。 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;
就是这样:)
该错误似乎与 state
将为空这一事实有关(因为没有定义初始本地状态)。 Redux 旨在提供来自提供程序组件的 uni-directional 数据流。您需要向下传递道具或从组件连接(尽管建议您仅连接 top-level 组件以避免丢失数据的来源)。任何时候 reducer returns 处于 new/updated 状态时,提供者都会再次将 props 传递给它的 children 并使它们成为 re-render。尝试连接 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 相关联(假设 routingReducer 来自 https://github.com/reactjs/react-router-redux). Try something like this -- https://jsfiddle.net/msindwan/bgto9c8c/
我正在开发我的第一个 'big' react-redux 应用程序。我正在尝试在组件之间映射 react-redux 状态,但似乎我错过了一些东西。
除一件事外,一切都像魅力一样:我的带有反应路线导航的菜单工作正常,我的组件已呈现,按钮 onClick 事件正常,我的其余部分 api 被调用,我返回 http 200使用适当的 json 数据添加到 redux 存储(我猜)。
唯一不起作用的是 this.state 在 TableRenderer.js.
中为 null我得到的错误与 redux 状态映射有关:
Uncaught TypeError: Cannot read property 'json' of null
App.js(主要class)
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(从 redux store 读取数据并渲染)
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(我的动作class)
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
});
}
更新: 感谢 Max Sindwani 的帮助,此问题已解决。有很多事情要解决。
App.js(主要class) 我的商店定义不正确
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 中缺少连接人员。它在 redux store 和 class locale props 之间绑定数据(如果我是正确的):
class TableRenderer extends React.Component {
render() {
return (
<div>
...
</div>
);
}
}
const mapStateToProps = (state) => {
return {
json: state.response.json
};
};
export default connect(mapStateToProps)(TableRender)
Reducers.js
我的 reducer 也是错误的,因为没有 switch 语句,在初始阶段,redux 以错误的方式初始化了 store。 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;
就是这样:)
该错误似乎与 state
将为空这一事实有关(因为没有定义初始本地状态)。 Redux 旨在提供来自提供程序组件的 uni-directional 数据流。您需要向下传递道具或从组件连接(尽管建议您仅连接 top-level 组件以避免丢失数据的来源)。任何时候 reducer returns 处于 new/updated 状态时,提供者都会再次将 props 传递给它的 children 并使它们成为 re-render。尝试连接 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 相关联(假设 routingReducer 来自 https://github.com/reactjs/react-router-redux). Try something like this -- https://jsfiddle.net/msindwan/bgto9c8c/