Search code examples
reactjsreact-context

React context value doesn't get updated


I was trying to implement a navigation drawer. First, I've made a navigation drawer layout that contain the nav drawer itself and the children, other components that appears whenever the navigation drawer is not displayed.

index.tsx

  const [active, setActive] = useState(false);

  function drawerActivationToggler() {
    console.log(active); // this logs the changes as expected
    setActive(!active)
  }

  return (
    <>
      <NavDrawerContext.Provider value={{ active: false, toggleActivation: drawerActivationToggler }}>
        <NavigationDrawerLayout active={active} direction="right" drawer={<div>hello</div>} >
          <NavBar></NavBar>
        </NavigationDrawerLayout>
      </NavDrawerContext.Provider>
    </>
  )

nav-bar.tsx

// some code...
<NavDrawerContext.Consumer>
    {
        ({ toggleActivation }) => {
            return (
                <li onClick={toggleActivation}><i className="fas fa-bars"></i></li>
            )
        }
    }
</NavDrawerContext.Consumer>

NavigationDrawerLayou.tsx

<NavDrawerContext.Consumer>
    {
        ({ active, toggleActivation }) => {
            console.log('inside ',active); // always false
            return (
                <div style={{ position: "relative", overflowX: "hidden" }}>
                    <section className={`${styles[`drawer-section-${direction}`]} ${active ? styles["active"] : ""}`}>{drawer}</section>
                    <section onClick={toggleActivation} className={`${styles[`shadow`]} ${active ? styles["active"] : ""}`}></section>
                    {/*children contains the navbar component that toggles activation*/}
                    <section style={{ height: "100vh", overflowY: active ? "hidden" : "scroll" }} className={`${styles[`children-section`]} ${active ? styles["active"] : ""}`}>{children}</section>
                </div>
            )
        }
    }
</NavDrawerContext.Consumer>

The log inside the toggling function itself works as expected however the log inside the consumer always returns false. Why this is happening?


Solution

  • That's because you always pass value active: false in the provider:

    <NavDrawerContext.Provider value={{ active: false, toggleActivation: drawerActivationToggler }}>
      <NavigationDrawerLayout active={active} direction="right" drawer={<div>hello</div>} >
        <NavBar></NavBar>
      </NavigationDrawerLayout>
    </NavDrawerContext.Provider>
    

    while it should be:

    <NavDrawerContext.Provider value={{ active, toggleActivation: drawerActivationToggler }}>
    ...