react js mapStateToProps 触发未捕获的类型错误:无法读取未定义的属性“地图" [英] react js mapStateToProps triggers Uncaught TypeError: Cannot read property 'map' of undefined

查看:44
本文介绍了react js mapStateToProps 触发未捕获的类型错误:无法读取未定义的属性“地图"的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个 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 在单独的 selectors.js 文件中 lib如下:

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屋!

查看全文
相关文章
其他开发最新文章
热门教程
热门工具
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆