使用 useContext 更新父组件
Updating Parent Component using useContext
我正在尝试从子组件更改父组件的状态。我的Component结构基本是这样的
<Admin>
<Nav/> //Nav Bar
{changePass && props.children} //Change Password Form
</Admin>
我的 Nav 依次有几个子组件:
<NavBar>
<NavItem menu="☰">
<DropdownMenu/>
</NavItem>
</NavBar>
在DropdownMenu 组件中有子按钮Components、Logout、Delete Account 和Change Password。后者是我想在 Admin.tsx 中切换更改密码组件的地方。在 DropdownItem.tsx 我有一些代码来检测按钮点击:
//ChangePassContext.tsx
import { createContext } from "react";
export let ChangePassContext = createContext<boolean>(false)
//DropdownItem.tsx
import { ChangePassContext } from "../Context/ChangePasswordContext/ChangePassContext";
let changePass = useContext(ChangePassContext)
//When window loads, get previous state from local storage
if (destination === CHANGEPSSWD){
if (localStorage.getItem('changePass') === "true"){
changePass = !changePass
}
}
const handleMenu = (event: MouseEvent) => {
event.preventDefault();
if (destination === CHANGEPSSWD) {
// Open Change Password Form
if (changePass === false){
localStorage.setItem('changePass', "true")
} else {
localStorage.removeItem('changePass')
}
changePass = !changePass
console.log(changePass)
window.location.reload() //I'll reference this in a moment
}
}
然后我在我的 Admin.tsx 文件中调用 changePass 并使用我在本地存储中存储的内容更新它:
let changePass = useContext(ChangePassContext)
if (localStorage.getItem("changePass") === "true"){
changePass = !changePass
}
并且如上所示,changePass 上下文控制 ChangePassword Form 是打开还是关闭:
{changePass && props.children} //Change Password Form
唯一的问题是我无法将状态从我的 DropdownItem 组件更新到我的 Admin 父组件。我可以让它更新的唯一方法是重新加载页面,就像我在 DropdownItem 组件中所做的那样,这会导致非常糟糕的用户体验:
具有讽刺意味的是,如您所见,我有一个可用的菜单组件(将 props 传递给子项似乎更容易),并且我使用 useContext 提供程序和 useState 完成了它。问题是,当我尝试使用 useState 设置上下文时,上下文不会更新,我不知道为什么。最初我尝试将我的 DropdownItem 函数设置为像这样简单的东西:
if (destination === CHANGEPSSWD) {
// Open Change Password Form
setChangePass(!changePass)
}
我也根本不想使用 localStorage,但没有它我似乎无法使用 useContext。
我很沮丧,尤其是这段代码有多难看。希望有人能帮忙。
像这样制作您的管理文件:
//Admin.tsx
import { createContext } from "react";
export const ChangePassContext = createContext();
function App() {
const[changePass, setChangePass] = useState({});
return (
<ChangePassContext.Provider value={[changePass, setChangePass]}>
<Admin>
<Nav/> //Nav Bar
{changePass && props.children} //Change Password Form
</Admin>
</UserContext.Provider>
);
}
export default App;
然后你就可以在你的DropdownItem.tsx
中使用它了
//DropdownItem.tsx
import { useContext } from 'react';
import { ChangePassContext } from '../../App';
const DropdownItem = () => {
const[changePass, setChangePass]= useContext(ChangePassContext);
if (destination === CHANGEPSSWD) {
// Open Change Password Form
setChangePass(!changePass)
}
return (
//your code
);
};
我正在尝试从子组件更改父组件的状态。我的Component结构基本是这样的
<Admin>
<Nav/> //Nav Bar
{changePass && props.children} //Change Password Form
</Admin>
我的 Nav 依次有几个子组件:
<NavBar>
<NavItem menu="☰">
<DropdownMenu/>
</NavItem>
</NavBar>
在DropdownMenu 组件中有子按钮Components、Logout、Delete Account 和Change Password。后者是我想在 Admin.tsx 中切换更改密码组件的地方。在 DropdownItem.tsx 我有一些代码来检测按钮点击:
//ChangePassContext.tsx
import { createContext } from "react";
export let ChangePassContext = createContext<boolean>(false)
//DropdownItem.tsx
import { ChangePassContext } from "../Context/ChangePasswordContext/ChangePassContext";
let changePass = useContext(ChangePassContext)
//When window loads, get previous state from local storage
if (destination === CHANGEPSSWD){
if (localStorage.getItem('changePass') === "true"){
changePass = !changePass
}
}
const handleMenu = (event: MouseEvent) => {
event.preventDefault();
if (destination === CHANGEPSSWD) {
// Open Change Password Form
if (changePass === false){
localStorage.setItem('changePass', "true")
} else {
localStorage.removeItem('changePass')
}
changePass = !changePass
console.log(changePass)
window.location.reload() //I'll reference this in a moment
}
}
然后我在我的 Admin.tsx 文件中调用 changePass 并使用我在本地存储中存储的内容更新它:
let changePass = useContext(ChangePassContext)
if (localStorage.getItem("changePass") === "true"){
changePass = !changePass
}
并且如上所示,changePass 上下文控制 ChangePassword Form 是打开还是关闭:
{changePass && props.children} //Change Password Form
唯一的问题是我无法将状态从我的 DropdownItem 组件更新到我的 Admin 父组件。我可以让它更新的唯一方法是重新加载页面,就像我在 DropdownItem 组件中所做的那样,这会导致非常糟糕的用户体验:
具有讽刺意味的是,如您所见,我有一个可用的菜单组件(将 props 传递给子项似乎更容易),并且我使用 useContext 提供程序和 useState 完成了它。问题是,当我尝试使用 useState 设置上下文时,上下文不会更新,我不知道为什么。最初我尝试将我的 DropdownItem 函数设置为像这样简单的东西:
if (destination === CHANGEPSSWD) {
// Open Change Password Form
setChangePass(!changePass)
}
我也根本不想使用 localStorage,但没有它我似乎无法使用 useContext。
我很沮丧,尤其是这段代码有多难看。希望有人能帮忙。
像这样制作您的管理文件:
//Admin.tsx
import { createContext } from "react";
export const ChangePassContext = createContext();
function App() {
const[changePass, setChangePass] = useState({});
return (
<ChangePassContext.Provider value={[changePass, setChangePass]}>
<Admin>
<Nav/> //Nav Bar
{changePass && props.children} //Change Password Form
</Admin>
</UserContext.Provider>
);
}
export default App;
然后你就可以在你的DropdownItem.tsx
中使用它了//DropdownItem.tsx
import { useContext } from 'react';
import { ChangePassContext } from '../../App';
const DropdownItem = () => {
const[changePass, setChangePass]= useContext(ChangePassContext);
if (destination === CHANGEPSSWD) {
// Open Change Password Form
setChangePass(!changePass)
}
return (
//your code
);
};