React Context传递Logout函数报错:onClick期望函数却获对象
问题分析与修复方案
你遇到的报错Expected onClick listener to be a function, instead got a value of object type,根源有两个关键问题,咱们一步步拆解解决:
1. Context Consumer 接收的是整个state对象,而非单独的logout函数
你在Root组件里把整个state对象传给了Provider的value:
<LogoutContext.Provider value={this.state}>
但在Navbar的Consumer里,你直接把接收的参数当成了logout函数:
{logout => ( <button onClick={logout}>Logout</button> )}
这里的logout其实是包含username、password等属性的完整state对象,并非你需要的函数,触发onClick时自然会报错。
修复方式二选一:
方式一:只传递logout函数给Provider
如果子组件只需要调用logout功能,没必要传递整个state,直接传函数即可:<LogoutContext.Provider value={this.state.logout}>这样Consumer里的
logout就是真正的函数,onClick调用就正常了。方式二:在Consumer里解构出logout函数
如果你需要传递整个state给子组件使用,那在Consumer里要正确解构属性:{({ logout }) => ( <nav> <ul> <li> <button onClick={logout}>Logout</button> </li> </ul> </nav> )}
2. Constructor里的函数绑定顺序错误,导致logout初始值为undefined
看你的Root组件constructor代码:
constructor(props) { super(props); this.state = { username: null, password: null, currentUsername: null, logout: this.handleLogout // 此时this.handleLogout还未被赋值! }; this.handleLogout = () => { this.setState({ currentUsername: null }); }; }
你先初始化了state,其中logout指向this.handleLogout,但此时this.handleLogout还没有被定义(箭头函数在后面才赋值),所以初始的state.logout是undefined。这会导致用户登录后第一次点击logout时可能无响应。
修复方法:调整顺序,先绑定函数再初始化state
constructor(props) { super(props); // 先定义handleLogout函数 this.handleLogout = () => { this.setState({ currentUsername: null }); }; // 再初始化state,此时this.handleLogout已经是有效的函数了 this.state = { username: null, password: null, currentUsername: null, logout: this.handleLogout }; }
把这两个问题修复后,你的logout功能就能正常触发了。
内容的提问来源于stack exchange,提问作者Mario
相关产品推荐
相关产品推荐

