react js mapStateToProps 触发未捕获的类型错误:无法读取未定义的属性“地图" [英] react js mapStateToProps triggers Uncaught TypeError: Cannot read property 'map' of undefined
问题描述
我有一个 index.js 来呈现数据库中的所有表.
_renderAllTables() {const { 获取} = this.props;让内容=假;如果(!获取){内容 = (<div className="tables-wrapper">{::this._renderTables(this.props.allTables)}
);}返回 (<部分><header className="view-header"><h3>所有表格</h3></标题>{内容}</节>);}_renderTables(表格){返回tables.map((table) => {返回<表键={table.id}dispatch={this.props.dispatch}{...表}/>;});}使成为() {返回 (<div className="视图容器表索引">{::this._renderAllTables()}
);}}const mapStateToProps = (状态) =>(状态.tables);导出默认连接(mapStateToProps)(HomeIndexView);
我将 mapStateToProps 从上面的代码改为下面的代码.
const mapStateToProps = (state) =>({表:state.tables,当前订单:state.currentOrder,});
我更改代码的原因是我想使用 currentOrder 的状态之一.我有一个状态显示表是否忙.所以为了使用它,我在 mapStateToProps 中添加了 currentOrder.但是,它会触发 Uncaught TypeError: Cannot read property 'map' of undefined..
如何使用来自其他组件的状态?对此有什么建议吗??
提前致谢..
--reducer.js
const initialState = {所有表:[],显示形式:假,获取:真实,表单错误:空,};导出默认函数reducer(state = initialState, action = {}) {开关(动作.类型){case Constants.TABLES_FETCHING:返回{...状态,获取:真};case Constants.TABLES_RECEIVED:return {...state, allTables: action.allTables, fetching: false};case Constants.TABLES_SHOW_FORM:return {...state, showForm: action.show};case Constants.TALBES_RESET:返回初始状态;case Constants.ORDERS_CREATE_ERROR:return { ...state, formErrors: action.errors };默认:返回状态;}}
你的问题是在成功获取 tables
之前,你的组件渲染时 state.tables
是 <代码>未定义代码>.
首先,最佳实践是使用选择器而不是像 state.tables
这样的 json 路径,使用 reselect 在单独的
lib如下:selectors.js
文件中
import { createSelector } from 'reselect';const tablesSelector = state =>状态表;导出默认{表选择器,}
其次,您需要为 FETCH_ALL_TABLES
操作使用 redux
库中的 combineReducers
添加减速器,最重要的是初始化 tables
数组和 []
在动作被分派之前定义如下:
从'redux'导入{combineReducers};功能表(状态 = [],{类型,有效载荷}){开关(类型){案例FETCH_ALL_TABLES":返回 [...状态,...有效载荷,]}返回状态;}导出默认的 combineReducers({桌子,});
在您的 index.js
中,可能需要将其更新为:
从'./selector'导入选择器;...函数 mapStateToProps(state) {返回 {表格:selector.tablesSelector(state),}}
I have an index.js which renders all tables in the database.
_renderAllTables() {
const { fetching } = this.props;
let content = false;
if(!fetching) {
content = (
<div className="tables-wrapper">
{::this._renderTables(this.props.allTables)}
</div>
);
}
return (
<section>
<header className="view-header">
<h3>All Tables</h3>
</header>
{content}
</section>
);
}
_renderTables(tables) {
return tables.map((table) => {
return <Table
key={table.id}
dispatch={this.props.dispatch}
{...table} />;
});
}
render() {
return (
<div className="view-container tables index">
{::this._renderAllTables()}
</div>
);
}
}
const mapStateToProps = (state) => (
state.tables);
export default connect(mapStateToProps)(HomeIndexView);
I changed mapStateToProps from above code to below code.
const mapStateToProps = (state) => ({
tables: state.tables,
currentOrder: state.currentOrder,
});
The reason why I changed code is that I want to use one of state of currentOrder. I have a state which shows whether table is busy or not. So in order to use that I added currentOrder in mapStateToProps. However, it triggers Uncaught TypeError: Cannot read property 'map' of undefined..
How can I use states from other components? any suggestions for that??
Thanks in advance..
--reducer.js
const initialState = {
allTables: [],
showForm: false,
fetching: true,
formErrors: null,
};
export default function reducer(state = initialState, action = {}) {
switch(action.type){
case Constants.TABLES_FETCHING:
return {...state, fetching: true};
case Constants.TABLES_RECEIVED:
return {...state, allTables: action.allTables, fetching: false};
case Constants.TABLES_SHOW_FORM:
return {...state, showForm: action.show};
case Constants.TALBES_RESET:
return initialState;
case Constants.ORDERS_CREATE_ERROR:
return { ...state, formErrors: action.errors };
default:
return state;
}
}
Your problem is that before fetching successfully tables
, your component is rendered with state.tables
is undefined
.
First of all, best practice is to use selectors rather than json path like state.tables
, to be in a separate selectors.js
file using reselect
lib as follow:
import { createSelector } from 'reselect';
const tablesSelector = state => state.tables;
export default {
tablesSelector,
}
Second, you need to add reducer for, let's assume, FETCH_ALL_TABLES
action using combineReducers
from redux
lib and most important to initialize tables
array with []
before the action is dispatched so as to be defined as follow:
import {combineReducers} from 'redux';
function tables(state = [], {type, payload}) {
switch (type) {
case 'FETCH_ALL_TABLES':
return [
...state,
...payload,
]
}
return state;
}
export default combineReducers({
tables,
});
and in your index.js
, may be want update it to:
import selector from './selector';
...
function mapStateToProps(state) {
return {
tables: selector.tablesSelector(state),
}
}
这篇关于react js mapStateToProps 触发未捕获的类型错误:无法读取未定义的属性“地图"的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!