You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

React-Native报错:TypeError: undefined is not a function(map调用异常)求助

问题:删除条目后触发 TypeError: undefined is not a function (near '...object.map...')

测试ItemList组件、reducer及action流程时,删除指定条目的功能逻辑生效,但操作后页面报错,提示对象无法调用map方法。

相关代码

ItemList.js

import React from 'react';
import { View, Text, StyleSheet } from 'react-native';
import { useDispatch, useSelector } from 'react-redux';
import { selectAllItems } from '../../../redux/reducer/itemReducer';
import { deleteItem } from '../../../redux/action/ItemAction';
import AppButton from '../../shared/AppButton';

const ItemList = () => {
  const dispatch = useDispatch();

  const itemData = useSelector(selectAllItems);
  function removeHandler(id){
    dispatch(deleteItem(id));
  }

  return (
    <>
      {itemData.map((item) => (
        <View style={styles.itemListContainer} key={item.id}>
          <Text style={styles.textStyle}>{item.id}</Text>
          <Text style={styles.textStyle}>{item.name}</Text>
          <Text style={styles.textStyle}>{item.price}</Text>
          <Text style={styles.textStyle}>{item.availableItem}</Text>
          <View style={styles.operationContainer}>
            <AppButton title="Edit" buttonStyle={buttonStyle.edit} textStyle={buttonStyle.text}/>
            <AppButton title="Remove"  buttonStyle={buttonStyle.remove} textStyle={buttonStyle.text} onPress={() => removeHandler(item.id)}/>
          </View>
        </View>
      ))}
    </>
  )
}

ItemReducer.js

const itemReducer = (state = initialState, { type, payload } = action) =>{
  switch (type) {
    case ADD_ITEM:
      return { ...state, payload };

    case DELETE_ITEM:
      return { payload };

    default:
      return state;
}
}

itemAction.js

function DELETE_ITEM(filtered){
  return{
    type: 'DELETE_ITEM',
    payload: filtered
  }
}

export function deleteItem(id){
  return function(dispatch, getState){
    const itemData = getState().item;
    const filtered = itemData.filter((item) => item.id !== id);
    dispatch(DELETE_ITEM(filtered));
  }
}

问题原因

核心问题是reducer维护的状态结构前后不一致:

  • 初始状态initialState应为数组(否则组件初始化时itemData.map也会报错),但在DELETE_ITEM分支中,你返回了{ payload },将状态从数组转换为了包含payload属性的对象。
  • 组件重新渲染时,itemData变成了对象,而对象没有map方法,因此触发报错。
  • 另外ADD_ITEM分支的返回值也错误,若初始状态是数组,{ ...state, payload }会把数组转为对象,同样会导致后续map失败。

解决方案

1. 修正reducer的状态更新逻辑

保持状态始终为数组结构:

const itemReducer = (state = initialState, { type, payload } = action) =>{
  switch (type) {
    case ADD_ITEM:
      return [...state, payload]; // 数组追加新元素,保持状态为数组
    case DELETE_ITEM:
      return payload; // action传入的payload已经是过滤后的数组,直接返回
    default:
      return state;
  }
}

2. 验证初始状态

确保initialState是数组类型,比如:

const initialState = []; // 或者包含初始条目的数组

原理说明

  • deleteItem action中已经通过filter得到了过滤后的条目数组,并将其作为payload传给reducer,因此reducer直接返回该数组即可维持正确的状态结构。
  • 之前的{ payload }会将状态包装成对象,导致组件获取的itemData不再是可遍历的数组,最终触发map调用失败的报错。

内容的提问来源于stack exchange,提问作者Almighty Dee

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.19 10:50:24