Reactjs 引起重招标的反作用钩

Reactjs 引起重招标的反作用钩,reactjs,typescript,jwt,Reactjs,Typescript,Jwt,我有一个钩子,它从本地存储读取令牌,并从令牌解码用户声明 export const useActiveUser=():{user:IUserTokenClaims | null}=>{ const[user,setUser]=useState(null); useffect(()=>{ const token=localStorage.getItem(“token”); 如果(!token)setUser(null); 否则{ const claims=jwt.解码(令牌)作为IUserToke

我有一个钩子,它从本地存储读取令牌,并从令牌解码用户声明

export const useActiveUser=():{user:IUserTokenClaims | null}=>{
const[user,setUser]=useState(null);
useffect(()=>{
const token=localStorage.getItem(“token”);
如果(!token)setUser(null);
否则{
const claims=jwt.解码(令牌)作为IUserTokenClaims;
如果(!claims.id | | |!claims.displayName | |!claims.role)setUser(null);
否则{
设置用户({
id:claims.id,
displayName:claims.displayName,
角色:索赔。角色
});
}
}
}, []);
返回{user};
};
如果我在这样的组件中使用钩子

export const SomeComponent:React.FC=()=>{
const{user}=useActiveUser();
console.log(用户)
if(user){/*如果用户登录,则渲染内容*/}
else{/*如果用户未登录,则渲染内容*/}
}
log语句将打印
null
,并在第二次渲染时注销用户声明


为什么会呈现两次?

您的
useActiveUser
钩子中的第一行:

const[user,setUser]=useState(null);
user
的初始值设置为
null
,您只需将
user
设置为装载(初始渲染)后运行的
useffect
挂钩中的另一个值。因此,在第一次渲染时,
用户
。您可以处理这个问题,也可以对代码进行一些修改以避免出现这种情况

通常,为了避免奇怪的渲染,您可以添加
isLoading
状态值,但是,这种方法最适合于必须异步设置的状态值(例如,通过调用API)。在这种情况下,您只需将
user
的初始值立即设置为计算值(因此无需
isload

例如,在设置
user
状态值并使用
usemo
挂钩之前,计算
user
的值:

export const useActiveUser=():{user:IUserTokenClaims | null}=>{
const user=useMemo(()=>{
const token=localStorage.getItem(“token”);
如果(!令牌){
返回null;
}否则{
const claims=jwt.解码(令牌)作为IUserTokenClaims;
如果(!claims.id | | |!claims.displayName | |!claims.role){
返回null;
}否则{
返回{
id:claims.id,
displayName:claims.displayName,
角色:索赔。角色
};
}
}
}, []);
返回{user};
};

它会重新加载两次,因为您正在
useffect
钩子中调用
setUser
,该钩子与类组件上的
componentDidMount
生命周期方法相同

  • 第一次渲染
  • user
    值为
    null
  • 组件已安装,
    useffect
    启动
  • 从localstorage解析用户
  • 设置已解析的用户
  • 触发第二个重新加载程序

  • 啊,我明白了,我没有意识到初始渲染时的默认值。你的解决方案有效。我现在删除了对
    setState
    的调用,并返回userData。在使用您提供的解决方案之前,我在实现中使用了
    isLoading
    。只是看起来。。。错了,哈哈。谢谢你的帮助。是的,当然。
    isLoading
    方法通常只适用于需要异步设置的状态值(例如调用API),但这里我们可以同步计算,因此不需要!