状态不随 useContext 改变
state do not change with useContext
你好
我正在尝试进行菜单切换,其中我有一个初始值为 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)
}
so 如果为 true 它将显示菜单 如果为 false 它将显示 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}
/>
)
})}
我哪里错了
问题
我怀疑问题出在 App
那里你有一个 useMenu
挂钩 在 之外 MenuProvider
使用 在App
。此 useMenu
挂钩使用 MenuContext
上下文,但在没有提供程序的情况下,它会使用默认的初始上下文值。
const initialState = {
isMenuOpen: true,
toggle: () => {},
};
export const MenuContext = React.createContext(initialState);
export const useMenu = () => {
return useContext(MenuContext)
};
const MyContext = React.createContext(defaultValue);
Creates a Context object. When React renders a component that
subscribes to this Context object it will read the current context
value from the closest matching Provider
above it in the tree.
The defaultValue
argument is only used when a component does not
have a matching Provider above it in the tree. This default value can
be helpful for testing components in isolation without wrapping them.
解决方案
因为我怀疑你想要 run/provide 多个菜单提供者我相信解决方案是将 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>
你好
我正在尝试进行菜单切换,其中我有一个初始值为 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)
}
so 如果为 true 它将显示菜单 如果为 false 它将显示 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}
/>
)
})}
我哪里错了
问题
我怀疑问题出在 App
那里你有一个 useMenu
挂钩 在 之外 MenuProvider
使用 在App
。此 useMenu
挂钩使用 MenuContext
上下文,但在没有提供程序的情况下,它会使用默认的初始上下文值。
const initialState = {
isMenuOpen: true,
toggle: () => {},
};
export const MenuContext = React.createContext(initialState);
export const useMenu = () => {
return useContext(MenuContext)
};
const MyContext = React.createContext(defaultValue);
Creates a Context object. When React renders a component that subscribes to this Context object it will read the current context value from the closest matching
Provider
above it in the tree.The
defaultValue
argument is only used when a component does not have a matching Provider above it in the tree. This default value can be helpful for testing components in isolation without wrapping them.
解决方案
因为我怀疑你想要 run/provide 多个菜单提供者我相信解决方案是将 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>