状态不随 useContext 改变

Posted

技术标签:

【中文标题】状态不随 useContext 改变【英文标题】:state do not change with 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,问题已解决,它是提供程序的错误放置 【参考方案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 的整个组件上,所以这个是一次学习经历,谢谢

以上是关于状态不随 useContext 改变的主要内容,如果未能解决你的问题,请参考以下文章

App字体大小不随系统改变而改变

父 div 的 toggleClass 不随 onClick 改变

反应不改变本地状态下拉值

React Hooks useContext 不允许状态更改

前端学习(3300):三种usecontent的

为啥表格单元格宽度不随 CSS 改变?