react js mapStateToProps 触发未捕获的类型错误:无法读取未定义的属性“地图”

IT技术 reactjs redux
2021-05-04 23:53:42

我有一个 index.js 呈现数据库中的所有表。

_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);

我将 mapStateToProps 从上面的代码更改为下面的代码。

 const mapStateToProps = (state) => ({
tables: state.tables,
currentOrder: state.currentOrder,
});

我更改代码的原因是我想使用 currentOrder 的状态之一。我有一个状态显示表是否忙。所以为了使用它,我在 mapStateToProps 中添加了 currentOrder。但是,它会触发 Uncaught TypeError: Cannot read property 'map' of undefined..

如何使用其他组件的状态?对此有何建议?

提前致谢..

--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;
   }
 }
2个回答

您的问题是在成功获取之前tables,您的组件是用state.tablesis呈现undefined

首先,最佳实践是使用选择器而不是像 json 路径state.tablesselectors.js使用reselectlib在一个单独的文件中,如下所示:

import { createSelector } from 'reselect';

const tablesSelector = state => state.tables;

export default {
  tablesSelector,
}

其次,您需要为FETCH_ALL_TABLES使用combineReducersfrom reduxlib 的action添加 reducer,最重要的是在调度 action 之前使用它来初始化tables数组,[]以便定义如下:

import {combineReducers} from 'redux';

function tables(state = [], {type, payload}) {
  switch (type) {
    case 'FETCH_ALL_TABLES':
      return [
        ...state,
        ...payload,
      ]
  }

  return state;
}


export default combineReducers({
  tables,
});

并且在您的index.js, 可能希望将其更新为:

import selector from './selector';

...

function mapStateToProps(state) {
  return {
    tables: selector.tablesSelector(state),
  }
}

您应该始终检查是否定义了要映射的变量。

_renderTables(tables) {
    if (tables) {
        return tables.map((table) => {
            return <Table
                key={table.id}
                dispatch={this.props.dispatch}
                {...table} />;               
        });
    }
}