React-Native + Redux:从 API 获取数据作为对象数组并在列表组件中呈现

React-Native + Redux: fetching data from API as an array of objects and rendering in list component

我一直在学习 React-Native + Redux,最近在尝试构建一个相对较小的应用程序时遇到了瓶颈。我的问题是,当我使用 axios 从 api(从我的另一个应用程序)获取 json 数据时,数据以对象数组的形式出现(例如所有门对象)。每当我尝试通过我的减速器将该数组传输到我的组件时,数据都会丢失并且数组每次都变为空

我的动作创建器,它使用 redux-thunk:

export const doorsFetch = () => {
  return (dispatch) => {
    axios.get('http://localhost:3000/api/v1/doors')
      .then(response => {
        dispatch({ type: FETCH_DOORS_SUCCESS, payload: response.data });
      })
      .catch(error => console.log(error.response.data));
  };
};

我的 DoorsReducer:

const INITIAL_STATE = [];

export default (state = INITIAL_STATE, action) => {
  console.log(action.payload);
  switch (action.type) {
    case FETCH_DOORS_SUCCESS:
      return [...state, action.payload];
    default:
      return state;
  }
};

action.payload console.log 出现了我所期望的,像这样的数组 [{object}, {object}]。但是在我的组件中,数组变为空,所以我认为问题出在 reducers 或我如何将状态映射到道具上。

我也试过这样的 doorReducer:

const INITIAL_STATE = {
  doors: []
};
export default (state = INITIAL_STATE, action) => {
  switch (action.type) {
    case FETCH_DOORS_SUCCESS:
      return { ...state, doors: action.payload };
    default:
      return state;
  }
};

与组件属性中的空数组的结果相同。

这是我的减速器索引:

import { combineReducers } from 'redux';
import OrientationReducer from './OrientationReducer';
import TraitsReducer from './TraitsReducer';
import DoorsReducer from './DoorsReducer';

export default combineReducers({
  orientation: OrientationReducer,
  traits: TraitsReducer,
  doorState: DoorsReducer
});

最后是我的组件 DoorList:

import React, { Component } from 'react';
import { connect } from 'react-redux';
import { ListView } from 'react-native';
import { doorsFetch } from '../actions';
import ListItem from './ListItem';

class DoorList extends Component {

  componentWillMount() {
    this.props.doorsFetch();

    this.createDataSource(this.props);
  }

  componentWillReceiveProps(nextProps) {
    this.createDataSource(nextProps);
  }

  createDataSource({ doors }) {
    const ds = new ListView.DataSource({
      rowHasChanged: (r1, r2) => r1 !== r2
    });

    this.dataSource = ds.cloneWithRows(doors);
  }

  renderRow(door) {
    return <ListItem door={door} />;
  }

  render() {
    console.log(this.props);  // for testing

    return (
      <ListView
        enableEmptySections
        dataSource={this.dataSource}
        renderRow={this.renderRow}
      />
    );
  }
}

const mapStateToProps = state => {
  return {
    doors: state.doorState
  };
};

export default connect(mapStateToProps, { doorsFetch })(DoorList);

当我控制台输出 this.props 时,我得到一个带有空门数组的对象。我似乎无法弄清楚数据发生了什么以及如何在视图中正确呈现它。任何见解将不胜感激。如果需要,很乐意提供更多 code/info。

编辑:

为了澄清,这是我为了调试目的放置 console.log 语句的地方:

const INITIAL_STATE = [];

export default (state = INITIAL_STATE, action) => {
  console.log(action.payload);
  console.log(action.type);
  switch (action.type) {
    case FETCH_DOORS_SUCCESS:
      console.log('fetching doors case triggered');
      return [...state, ...action.payload];
    default:
      console.log('not working!');
      return state;
  }
};

解决方案:

除了下面建议的更正之外,另一个明显的问题是我的 FETCH_DOORS_SUCCESS 常量不正确地从另一个文件导入,因此在 reducer 文件中未定义。因此,我的 switch 语句没有接受它,它进入了默认情况。我在 FETCH_DOORS_SUCCESS 周围缺少大括号。

如果action.payload是一个数组,你还需要在上面加上展开运算符,以便与state中的数组正确组合:

变化:

case FETCH_DOORS_SUCCESS:
  return [...state, action.payload];

至:

case FETCH_DOORS_SUCCESS:
  return [...state, ...action.payload];

您似乎也没有返回 axios.get() 的承诺:

改变这个:

return (dispatch) => {
  axios.get('http://localhost:3000/api/v1/doors')

return (dispatch) => {
  return axios.get('http://localhost:3000/api/v1/doors')