【问题标题】:state do not change with useContext状态不随 useContext 改变
【发布时间】:2021-07-14 05:41:11
【问题描述】:

你好

我正在尝试进行菜单切换,其中我有一个初始值为 false 的变量,使用 react createContext 和 useContext 挂钩,我将初始状态设置为 true

// useMenu Context
import React, { useContext, useState } from 'react'

export const useToggle = (initialState) => {
  const [isToggled, setToggle] = useState(initialState)
  const toggle = () => setToggle((prevState) => !prevState)
  // return [isToggled, toggle];
  return { isToggled, setToggle, toggle }
}

const initialState = {
  isMenuOpen: true,
  toggle: () => {},
}

export const MenuContext = React.createContext(initialState)

const MenuProvider = ({ children }) => {
  const { isToggled, setToggle, toggle } = useToggle(false)
  const closeMenu = () => setToggle(false)
  return (
    <MenuContext.Provider
      value={{
        isMenuOpen: isToggled,
        toggleMenu: toggle,
        closeMenu,
      }}>
      {children}
    </MenuContext.Provider>
  )
}
export default MenuProvider

export const useMenu = () => {
  return useContext(MenuContext)
}

所以如果为真,它将显示菜单,如果为假,它将显示有 div 的 Div

App.js

const { isMenuOpen } = useMenu()

//the providder
<MenuProvider>
  <Header mode={theme} modeFunc={toggleTheme}/>
      {isMenuOpen ? (
         <Menu />
      ) : (
      <Switch>
        <Route path='/writing' component={Writings} />
        <Route path='/meta' component={Meta} />
        <Route path='/contact' component={Contact} />
        <Route path='/project' component={Project} />
        <Route exact path='/' component={Home} />
        <Route path='*' component={NotFound} />
      </Switch>
    )}
  <Footer />{' '}
</MenuProvider>

当我添加一个 onclick 事件时,菜单的 NavLink 按钮关闭它不起作用

菜单


const { closeMenu } = useMenu()
// return statement
{paths.map((item, i) => {
  return (
    <MenuItem
      key={i}
      link={item.location}
      svg={item.icon}
      path={item.name}
      command={item.command}
      onClick={closeMenu}
     />
  )
})}

我哪里做错了

【问题讨论】:

  • 为了清楚起见,您能否详细说明&lt;Menu /&gt; 现在正在做什么?是“保持开放”吗?
  • @MichaelHoobler 这是一个包含列表的组件,我想我在最后一段代码中解释了其中 MenuItem 表示 NavLink 组件
  • @Jargarkin,我的意思是“意外行为”是什么:组件当前正在做什么与组件应该做什么相比>”。
  • @MichaelHoobler 的意图行为是在 isMenuOpen 为 false 时隐藏菜单,但是当将其更改为 false 时它始终保持为 true,问题已解决,它是提供程序的错误放置

标签: javascript reactjs react-hooks react-context use-context


【解决方案1】:

问题

我怀疑问题出在App 中,您有一个useMenu 挂钩MenuProvider 使用inApp。这个useMenu 挂钩使用MenuContext 上下文,但在没有提供程序的情况下,它使用默认的初始上下文值。

const initialState = {
  isMenuOpen: true,
  toggle: () => {},
};

export const MenuContext = React.createContext(initialState);

export const useMenu = () => {
  return useContext(MenuContext)
};

React.createContext

const MyContext = React.createContext(defaultValue);

创建一个上下文对象。当 React 渲染一个组件时 订阅此 Context 对象,它将读取当前上下文 树中最接近匹配的Provider 的值。

defaultValue 参数在组件不支持时使用 在树的上方有一个匹配的 Provider。 这个默认值可以 有助于在不包装组件的情况下单独测试组件。

解决方案

由于我怀疑您想运行/提供多个菜单提供程序,我相信解决方案是将MenuProvider 移出并包装App 以提供您通过嵌套组件更新的上下文。

App.jsx

const { isMenuOpen } = useMenu();

...

<>
  <Header mode={theme} modeFunc={toggleTheme}/>
  {isMenuOpen ? (
    <Menu />
  ) : (
    <Switch>
      <Route path='/writing' component={Writings} />
      <Route path='/meta' component={Meta} />
      <Route path='/contact' component={Contact} />
      <Route path='/project' component={Project} />
      <Route exact path='/' component={Home} />
      <Route path='*' component={NotFound} />
    </Switch>
  )}
  <Footer />
</>

index.jsx (?)

import App from './App.jsx';

...

//the provider
<MenuProvider>
  <App />
</MenuProvider>

【讨论】:

  • 它起作用了,我怀疑 MenuProvider 和它在代码中的位置与状态冻结有关,但由于它会包裹在我刚刚放入 App.jsx 的整个组件上,所以这个是一次学习经历,谢谢
猜你喜欢
  • 2021-06-16
  • 1970-01-01
  • 2021-03-17
  • 2022-12-12
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-03-16
  • 2021-07-01
相关资源
最近更新 更多