REACT NATIVE REDUX如何在动作创建者接收的reducer中设置数组

时间:2018-03-22 15:03:59

标签: javascript arrays reactjs react-native redux

我正在尝试将数组调度到我的reducer,并将其设置为我的状态以在组件上使用它。它适用于对象,但我无法弄清楚如何使用数组。

我的动作创作者:

export const loadUserItems = () => {
  return async function(dispatch) {
    const url_current = 'https://whateverapi';
    const response = await axios.get(url_current);
    const items = response.data.items;
    dispatch(loadItems(items));
  }
}

function loadItems(data) {
  return {
    type: LOAD_USER_ITEMS,
    payload: data
  };
}

因此,如果我在我的数组中获得一个项目,它的工作完全正常。 我可以将它设置为我的reducer中的一个对象,并在我的组件上使用它。

我的减速机:

import {
  LOAD_USER_ITEMS
} from '../actions/types';

const INITIAL_STATE = {
  items: []
};

export default (state = INITIAL_STATE, action) => {
  switch (action.type) {
    case LOAD_USER_ITEMS :
      return {
        items: action.payload
      };
    default:
      return state;
  }
};

所以在这里,action.payload是一个数组,我可以控制它.log它输出我的数组。该数组包含一些JSON对象。

但是当我尝试在我的组件中访问它时,它告诉我它未定义

import ... (no problems here)
class HomePage extends Component {
  loadUserItems() {
    this.props.loadUserItems();
  }
  constructor(props) {
    super(props);
    this.loadUserItems();
  }
  render() {
    return (
      <Container>
        <Content>
        <View style={styles.headerViewStyle}>
          <Image
            style={styles.headerImageStyle}
            source={require("../assets/images/header.png")}
          />
        </View>
          <View>
            <ItemSquareDisplay description={this.props.items[0].type}/>
          </View>
        </Content>
      </Container>
    );
  }
}
const mapStateToProps = state => {
  return {
    items: state.items.items,
  };
};
export default connect(mapStateToProps, {loadUserItems}) ( HomePage );

我的数组包含项目,第一项.type是'冰箱'...... 但它告诉我this.props.items [0] .type未定义。 我做了同样的事情,但只是派出了第一个项目,它工作正常,我可以访问this.props.items.type。但是,如果我发送整个阵列,它似乎不起作用。

再次需要你们! 感谢

2 个答案:

答案 0 :(得分:1)

原因是您正在访问一个空数组。

最初,您的item数组是reducer中的空数组。现在,在组件内部调用您的操作loadUserItems,这将花费大量时间来获取数据并更新redux存储。在这段时间内,组件的render方法执行并尝试访问空数组的第一个元素,这肯定会产生错误。

所以你可以轻松做的是在访问它的元素之前检查数组是否为空。

 <ItemSquareDisplay description={this.props.items && this.props.items.length > 0 ? this.props.items[0].type : ''} /> 

请注意,使用对象时工作的原因是幸运的是,在渲染方法执行和访问数组之前,操作已更新了redux存储。

答案 1 :(得分:1)

应该在reducer中使用不可变变量。

您可以使用slice()concat()

在你的情况下:

case LOAD_USER_ITEMS :
      return {
        items: action.payload.slice()
      };

或者如果你想在

之后在每个负载上添加更多项目
case LOAD_USER_ITEMS :
      return {
        items: state.items.concat(action.payload)
      };

确保有效负载是一个数组