状态不随 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
/>
)
)
我哪里做错了
【问题讨论】:
为了清楚起见,您能否详细说明<Menu />
现在正在做什么?是“保持开放”吗?
@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 改变的主要内容,如果未能解决你的问题,请参考以下文章
父 div 的 toggleClass 不随 onClick 改变