执行React教程代码时遇props.deleteComments not a function错误求助
props.deleteComments not a function错误的思路与解决办法 嘿,这个报错我之前在做React组件传参的时候也踩过坑,咱们来一步步揪出问题根源,再搞定它:
为什么会出现这个错误?
本质上就是你的CommentsList组件拿到的deleteComments根本不是一个可调用的函数,大概率是下面这几个原因中的一个:
1. App组件里的deleteComments方法没正确绑定this
虽然你用了箭头函数定义deleteComments(这种写法会自动绑定组件实例的this),但如果是用普通函数写法又没绑定的话,方法里的this会变成undefined,甚至在传递给子组件时可能被误处理成非函数值。不过看你当前的代码写法,这一步可能没问题,但还是得确认下。
2. 给CommentsList传属性的时候写错了名字
比如你在App里渲染CommentsList时,可能把deleteComments写成了deleteComment(少了个s),或者别的拼写错误,导致子组件的props里找不到正确的函数,自然就会报“不是函数”的错。
3. 压根没给CommentsList传deleteComments属性
如果在App的render里写<CommentsList comments={this.state.comments} />,忘了加deleteComments={this.deleteComments},那props.deleteComments就是undefined,肯定不是函数。
一步步修复的办法
第一步:确认deleteComments的this绑定没问题
你现在用箭头函数定义方法的写法是对的,箭头函数会自动绑定组件实例的this,这一步可以跳过。但如果你哪天改成普通函数写法,一定要在构造函数里绑定:
class App extends React.Component { constructor(props) { super(props); this.state = { comments: [] }; // 必须绑定this! this.deleteComments = this.deleteComments.bind(this); } // 普通函数写法的deleteComments async deleteComments(commentId) { try { await axios.delete(`/comments/${commentId}`); const comments = await this.getComments(); this.setState({ comments }); } catch (error) { console.log(error); } } }
第二步:检查App里传递属性的代码
打开App的render方法,确保你给CommentsList传对了属性,比如:
render() { return ( <div className="app-container"> {/* 重点看这里:属性名要和子组件里用的完全一致,函数要指向实例的deleteComments */} <CommentsList comments={this.state.comments} deleteComments={this.deleteComments} /> </div> ); }
仔细核对拼写,别少字母多字母,大小写也要一致。
第三步:给子组件加个防御性检查(可选但推荐)
为了避免这类报错影响用户体验,你可以在CommentsList里先判断一下props.deleteComments是不是函数,再传给Comment组件:
const CommentsList = (props) => { const comments = props.comments.map((comment) => { // 先做个判断,确保是函数再传递 const handleDelete = typeof props.deleteComments === 'function' ? () => props.deleteComments(comment.id) : () => console.warn('deleteComments 方法未正确传递'); return ( <Comment {...comment} deleteComments={handleDelete} key={comment.id} /> ); }); return <div className="comments-list">{comments}</div>; };
额外排查小技巧
如果上面的步骤都试过还没解决,那可以看看:
- 有没有在其他地方不小心把
deleteComments重写成了非函数值?比如某个地方赋值成了字符串或者undefined; - 检查
getComments方法是否正常返回数据,不过这和当前报错无关,但如果这个方法有问题,后续更新状态也会出问题。
内容的提问来源于stack exchange,提问作者mwlai

