我混合使用useContext
和useEffect将useContext
数据持久化在本地存储中。由于条件呈现,我无法这样做。这里的情况是,我希望在用户未登录时有一个登录按钮,在用户登录时有一个注销按钮。
在Codesanbox中,我修复了模态中的登录按钮,将“user”的初始空状态更改为“User is logged in”。
在SignInDialog.js
中,我有一个useEffect
,我将登录模态的isOpe
n prop作为依赖值传递给它。因此,每次打开和关闭它时,它都应该记录“useEffect setItem 2”。只打开模态并通过单击侧面来关闭它的测试带来了成功的结果。在我按下模态中的登录按钮后,模态关闭。但是useEffect
没有被触发。
然后,在父组件中使用“user”的值来有条件地呈现“sign in”或“log-out”按钮。
当我删除它时,一切都按预期工作。问题似乎是呈现父组件和子组件的顺序。我想不出一种方法来解决这个问题,而不改变我的方法。
用户上下文.js
import { createContext } from "react";
export const UserContext = createContext(null);
应用程序js
export default function App() {
const [user, setUser] = useState();
return (
<div className="App">
<UserContext.Provider value={{ user, setUser }}>
<Main />
</UserContext.Provider>
</div>
);
}
主文件.js
export default function Main() {
const { user, setUser } = useContext(UserContext);
const logOut = () => {
setUser(null);
};
return (
<div className="App">
{/* If I only have SignInButton and no conditional render it works */}
{/* <div>
<SignInButton />
</div> */}
{user ? (
<div>
<Typography>{user}</Typography>
<Button onClick={logOut}>Log out</Button>
</div>
) : (
<div>
<SignInButton />
</div>
)}
</div>
);
}
登录按钮.js
const SignInButton = () => {
const [openSignInDialog, setOpenSignInDialog] = useState(false);
const handleSignInClickOpen = () => {
setOpenSignInDialog(true);
};
return (
<StyledEngineProvider injectFirst={true}>
<div>
<Button onClick={handleSignInClickOpen}> Sign in </Button>
<SignInDialog open={openSignInDialog} setOpen={setOpenSignInDialog} />
</div>
</StyledEngineProvider>
);
};
export default SignInButton;
登录对话框.js
export default function SignInDialog(props) {
const { user, setUser } = useContext(UserContext);
useEffect(() => {
console.log(">>>>>>>useEffect getItem 1");
/* const data = window.localStorage.getItem('uli')
console.log(`data = ${data}`) */
}, []);
useEffect(() => {
console.log(">>>>>>>useEffect setItem 2");
/* window.localStorage.setItem('uli', user) */
}, [props.open]);
{
/* end goal is to pass user as dependency but left like this for testing purposes */
}
const test = () => {
setUser("User logged in");
props.setOpen(false);
{
/* props.setOpen(false) doesn't make no difference */
}
};
const handleClose = () => {
props.setOpen(false);
};
return (
<div className="App">
<Dialog open={props.open} onClose={handleClose}>
<Box component="form">
<DialogTitle>Sign in data</DialogTitle>
<DialogContent>
<DialogContentText>username, password..</DialogContentText>
</DialogContent>
<DialogActions>
<Button type="button" onClick={test}>
Sign in
</Button>
</DialogActions>
</Box>
</Dialog>
</div>
);
}
1条答案
按热度按时间w46czmvw1#
在
SignInDialog.js
中,你正在设置useEffect
中的本地存储,并将props.open
作为依赖项。因此您的useEffect
从未运行。您可以按如下所示更改test
并删除该useEffect
:然后,在
App.js
中,按如下所示更改user
定义,因此,在此之前,您将检索本地存储(如果有)中的内容: