Mario
Mario

Reputation: 4998

trying to execute a function that is passed to a component using context

I am trying to learn the concept of context in react, I am trying to pass a function that closes the current user session to a component using context, I am following the context guide in the Updating Context from a Nested Component section, but when clicking on the logout button I get the following message Expected onClick listener to be a function, instead got a value of object type.

The code is the following

I create the context with an empty function as default value

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

The Root component has as state property that call the logout handler and I am passing as a Provider value the whole state, as I read in the documentation

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 />
    );
  }
}

The dashboard component renders the Navbar component which is the component that receives the function using context that I need to execute

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

In the target component I am expecting for the function to be executed by clicking on the logout button, but instead I get the error message mentioned

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

I thank your observations

Upvotes: 1

Views: 132

Answers (1)

Robb Traister
Robb Traister

Reputation: 147

There are 2 issues First, you're passing the entire state object as the value of your context provider, when it seems as though you only want to pass the logout function. Second, the logout property is set on state before this.handleLogout is defined, so it should have a value of undefined.

State should only be used for values that are going to change through the course of the component's lifecycle. The easy fix is to just remove logout from state and pass this.handleLogout as your context value.

Upvotes: 2

Related Questions