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

Redux的addList action在组件中无法触发,报Uncaught TypeError错误

问题分析与解决方案

首先,你遇到的Uncaught TypeError: addList is not a function错误,核心原因是ListTable组件的props参数解构写法错误,同时组件内的state更新逻辑也存在小问题,下面一步步拆解修复:

错误根源

React组件接收的props是一个单一的对象参数,但你在ListTable里写成了:

const ListTable = (list, {addList}) => { 

这里的第一个参数list其实是完整的props对象,第二个参数{addList}根本不存在(React不会给组件传递第二个参数),所以addList会是undefined,自然就不是一个函数。而AddList组件的写法({ addList })是正确的——它从单个props对象里解构出了addList,所以能正常工作。

另外,你代码里setData({ d })的写法会把数组类型的data变成对象(格式为{d: [数组内容]}),这会导致后续MaterialTable的数据渲染和addList调用出错,也需要修正。

修正后的ListTable组件代码

import React, { useState } from "react"; 
import MaterialTable from "material-table"; 
import { addList } from '../../actions/profile'; 
import PropTypes from "prop-types"; 
import { connect } from "react-redux"; 

// 修正:从单个props对象中解构list和addList
const ListTable = ({ list, addList }) => { 
  // 初始化state为传入的list数组,简化变量处理
  const [data, setData] = useState(list.list); 
  const listname = list.name; 

  const handlebClick = (e) => { 
    e.preventDefault(); 
    console.log({list}); 
  }; 

  return ( 
    <div className="list-table"> 
      <button onClick={e => handlebClick(e)}>Apply Sequence</button> 
      <MaterialTable 
        title={listname} 
        columns={[ 
          { title: "User Name", field: "username" }, 
          { title: "Link", field: "link", initialEditValue: "" }, 
          { title: "Name", field: "name", initialEditValue: "" }, 
          { title: "Source", field: "source", initialEditValue: "" }, 
          { title: "Date Added", field: "dateAdded", type: "date" }, 
          { title: "Notes", field: "notes", initialEditValue: "" } 
        ]} 
        data={data} 
        editable={{ 
          onRowAdd: newData => new Promise((resolve, reject) => { 
            setTimeout(() => { 
              // 修正:创建新数组保证state不可变性,避免直接修改原数组
              const newDataArr = [...data, newData];
              setData(newDataArr); 
              console.log(newDataArr); 
              addList(newDataArr, listname, true); 
              resolve(); 
            }, 1000); 
          }), 
          onRowUpdate: (newData, oldData) => new Promise((resolve, reject) => { 
            setTimeout(() => { 
              const newDataArr = [...data];
              const index = newDataArr.indexOf(oldData); 
              newDataArr[index] = newData; 
              setData(newDataArr); 
              resolve(); 
            }, 1000); 
          }), 
          onRowDelete: oldData => new Promise((resolve, reject) => { 
            setTimeout(() => { 
              if (data.length > 0) { 
                // 用filter更简洁地删除元素,同时保证不可变性
                const newDataArr = data.filter(item => item !== oldData);
                setData(newDataArr); 
              } 
              resolve(); 
            }, 1000); 
          }) 
        }} 
      /> 
    </div> 
  ); 
}; 

ListTable.propTypes = { 
  addList: PropTypes.func.isRequired,
  list: PropTypes.object.isRequired // 补充list的prop类型校验,让代码更健壮
}; 

export default connect( 
  null, 
  { addList } 
)(ListTable);

关键修正点总结

  • 修正props解构方式:把(list, {addList})改成({ list, addList }),确保从正确的props对象中获取addList函数。
  • 修正state更新逻辑:不再直接修改原数组,而是通过扩展运算符[...data]或filter创建新数组,保证state的不可变性,同时避免把数组变成对象。
  • 简化冗余代码:去掉了不必要的变量赋值(比如const l = list;、list = l.list.list;),直接使用解构后的属性,让代码更清晰易读。

这样修改后,addList就能正常调用,同时state的更新也符合React的规范,不会出现后续的数据异常。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.14 07:48:58