新的反应和钩子,我正在尝试使用钩子做一个登录模块。但是,当我无法更新我的 Auth 状态时。在别处读到 useState 不会立即更新,需要与 useEffect() 结合才能更新。但是我在自定义钩子中使用 useState 并且不确定如何通过 useEffect 或其他方式进行更新。
我在这里做某种反模式吗?有人可以帮忙吗?
const useAuth = () => {
const [auth, setAuth] = useState( {} );
useEffect(()=>{
console.log(auth)
},[])
return {auth, setAuth}
}
export const useHandleLogin = (props) => {
const {auth, setAuth} = useAuth()
const history = useHistory();
useEffect(()=>{
console.log(auth)
},[])
const login = () => {
console.log('login action called---- ');
/* check if user is login */
if(localStorage.getItem('user')){
console.log('got user' );
} else {
console.log('no user, calling backend to authenticate... ' );
// change to login api
axios.get(`http://localhost:3001/projects`)
.then(res => {
console.log('call api' /* + JSON.stringify(res) */);
})
localStorage.setItem('user', JSON.stringify({username:'abc',role:'123'}))
console.log('login done' + JSON.stringify(auth));
console.log('login done2' + auth.authenticated);
}
setAuth({
authenticated: true,
displayName: 'My Name',
email: 'xxx@abc.com',
role: 'admin'
})
console.log("sending to success page" + auth + JSON.stringify(auth)) // Error is here. output is : sending to success page[object Object]{}
import React, {useEffect} from "react";
import { useHandleLogin } from "./LoginUtil"
const TestLoginPage = () => {
const { auth, login } = useHandleLogin();
const Clogin = () => {
console.log('auth: ' + auth)
login();
};
return (
<React.Fragment>
<div>login</div>
<button onClick={Clogin} > Login </button>
</React.Fragment>
);
}
export default TestLoginPage;
答案 0 :(得分:0)
似乎您缺少在 useEffect()
依赖项数组中添加一些依赖项。此外,为了生成像 login()
这样的回调的新实例,您应该将它包装在 useCallback()
中并在数组中添加必要的依赖项。从外观上看,
useEffect()
缺少依赖项数组中的 auth
login()
应包含在 useCallback()
中,并且必须具有 auth
依赖项
数组Clogin()
必须包含在 useCallback()
中,并且必须有 auth
和 login
在依赖数组中您可以使用 add eslint-plugin-react-hooks
,它可以帮助您在错过依赖项时提示警告。
答案 1 :(得分:0)
经过几天的尝试和阅读,以下是我认为正确的实现方式。
import React, { useState, useEffect } from "react";
import { useHistory } from "react-router-dom";
import { Redirect } from "react-router-dom";
import axios from 'axios';
export const useAuth = (props) => {
/* const init = localStorage.getItem('user1')? true : false */
const init = {authen : false}
const [auth, setAuth] = useState(init);
const history = useHistory();
console.log("auth initial " + auth)
const checkAuthStatus = () => {
return !!auth.authen
}
const login = () => {
console.log('login action called---- ');
let success = true
if(success){
setAuth({authen : true})
}else{
setAuth ({authen : false})
}
console.log('push history==========' )
/* history.push('/testLoginOK');
history.go(); */
}
const logout = () => {
console.log('logout action called---- ');
setAuth ({authen : false})
history.push('/testLogin');
history.go();
}
useEffect(() => {
console.log("useEffect auth "+auth.authen)
if(!!auth.authen){
/* history.push('/testLoginOK');
history.go(); */
}
})
return {auth, checkAuthStatus, login, logout}
}
/* export default useAuth */