【问题标题】:trying to execute a function that is passed to a component using context尝试使用上下文执行传递给组件的函数
【发布时间】:2019-10-19 15:38:40
【问题描述】:

我正在尝试在 react 中学习 context 的概念,我正在尝试使用上下文将关闭当前用户会话的函数传递给组件,我正在遵循 Updating Context from a Nested Component 部分中的上下文指南,但是单击注销按钮时,我收到以下消息Expected onClick listener to be a function, instead got a value of object type.

代码如下

我使用空函数作为默认值创建上下文

const LogoutContext = React.createContext(() => {});

根组件具有调用注销处理程序的 state 属性,并且我将整个状态作为 Provider 值传递,正如我在文档中阅读的那样

class Root extends Component {
  constructor(props) {
    super(props);

    this.state = {
      username: null,
      password: null,
      currentUsername: null,
      logout: this.handleLogout 
    };

    this.handleLogout = () => {
      this.setState({ currentUsername: null });
    };    
  }

  render() {
    const currentUsername = this.state.currentUsername;

    if (currentUsername) {
      return (
        <LogoutContext.Provider value={this.state}>
          <Dashboard username={currentUsername} />
        </LogoutContext.Provider>
      );
    }

    return (
      <Login />
    );
  }
}

仪表板组件呈现导航栏组件,该组件是使用我需要执行的上下文接收功能的组件

function Dashboard(props) {
  return (
    <div>
      <Navbar />
      <Main />
    </div>
  );
}

在目标组件中,我希望通过单击注销按钮来执行该功能,但我收到了提到的错误消息

function Navbar(props) {
  return (
    <LogoutContext.Consumer>
      {logout => (
        <nav>
          <ul>
            <li>
              <button onClick={logout}>Logout</button>
            </li>
          </ul>
        </nav>
      )}
    </LogoutContext.Consumer>
  );
}

感谢您的观察

【问题讨论】:

  • createContext 需要一个对象,而不是返回对象的函数。 React.createContext({})React.createContext((() =&gt; {})()) 都是有效的,因为它们提供了预期的参数类型。但是,除此之外,我不明白您要做什么,因此我无法提供答案。
  • 谢谢你的回答,你能举个例子吗
  • 它的要点是() =&gt; {} 不等同于{}(() =&gt; {})()。首先是一个函数返回一个对象 whenif 它运行(永远不会发生,除非你运行它)。第二个和第三个 对象,因为这是它们在解析/读取时“变成”的对象(因为函数正在运行)。我希望我说得够清楚。

标签: javascript reactjs react-context


【解决方案1】:

有两个问题首先,您将整个状态对象作为上下文提供程序的值传递,而您似乎只想传递注销功能。其次,logout 属性设置在this.handleLogout 定义之前的状态,所以它的值应该是 undefined。

State 应该只用于在组件的生命周期中会发生变化的值。简单的解决方法是从状态中删除注销并将this.handleLogout 作为您的上下文值传递。

【讨论】:

  • 感谢 Robb,应用您的建议解决了问题
猜你喜欢
  • 1970-01-01
  • 2018-01-23
  • 2018-09-30
  • 1970-01-01
  • 1970-01-01
  • 2020-08-19
  • 1970-01-01
  • 2020-01-26
  • 1970-01-01
相关资源
最近更新 更多