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
相关产品推荐
相关产品推荐

