我有2个定制的钩子。一种是处理令牌(useToken),另一种是逐个令牌解码用户(useUser)。现在我希望每次在我的自定义钩子useUser中更新token,但它从未触发,我添加了[token]作为依赖项,但没有useEffect调用。
import { useState, useEffect } from "react";
function getToken() {
return window.localStorage.getItem("token");
}
function useToken() {
const [token, updateToken] = useState(() => getToken());
const setToken = (newToken) => {
localStorage.setItem("token", newToken);
updateToken(newToken);
};
return [token, setToken];
}
const getUserFromToken = (token) => {
if (!token) return null;
return token + Date().toString();
};
function useUser() {
const [token] = useToken();
const [user, setUser] = useState(() => getUserFromToken(token));
useEffect(() => {
if (!token) return;
const newUser = getUserFromToken(token);
setUser(newUser);
}, [token]);
return user;
}
export default function App() {
const [token, setToken] = useToken();
const user = useUser();
const [userName, setUserName] = useState("");
const handleChange = (e) => setUserName(e.target.value);
const saveHandler = () => {
setToken(userName);
};
return (
<div className="App">
<div>
<input
type="text"
placeholder="Enter Username"
value={userName}
onChange={handleChange}
/>
<button onClick={saveHandler}>Save</button>
</div>
<div>User - {user}</div>
</div>
);
}
我也尝试使用useMemo代替useUser钩子中的useEffect,但都不起作用。怎么了?
1条答案
按热度按时间kx1ctssn1#
请允许我解释一下发生了什么。您的自定义钩子
useUser
正在使用它自己的 * 版本 * 的useToken
钩子。因此,当通过调用setToken
在App
内部更新实际令牌时,它只更新App
组件内部的token
。请注意,即使您更新了
App
中的标记,钩子useUser
仍然有自己的标记版本。自定义钩子不会神奇地相互交谈,除非使用类似useContext的东西。解决办法很简单。我们将把App的token传递给
useUser
钩子,一切都将正常工作。不过,我想提出另一项忠告。我可以看到
useUser
钩子并没有做太多的事情。它基本上处理它得到的任何token
,并在不执行任何操作的情况下溢出user
。对于这个用例,保持一个单独的状态并在useUser
内部使用useEffect
似乎是不必要的。由于user
总是从令牌中派生出来的,这似乎是使用useMemo
的一个很好的例子。因此,useUser
可以简化如下:我希望这一切都有意义。:)