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

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.14 08:16:39