我使用 recoil 进行状态管理,用于练习一个非常基本的待办事项应用程序,但我的 todolist.tsx 没有显示更新的用户名,我需要每次刷新才能看到更新的用户名和待办事项在用户名更改后立即更改。我无法弄清楚这个问题。
这是我的身份验证状态
import { atom } from 'recoil';
export const authState = atom({
key: 'authState',
default: { token: null, username: null },
});
这是初始状态
function InitState() {
const setAuth = useSetRecoilState(authState);
const navigate = useNavigate();
const init = async () => {
const token = localStorage.getItem("token");
try {
const response = await fetch('http://localhost:3000/auth/me', {
headers: { Authorization: `Bearer ${token}` }
});
const data = await response.json();
console.log(data);
console.log(data.username);
if (data.username) {
setAuth({ token: data.token, username: data.username });
navigate("/todos");
} else {
navigate("/login");
}
} catch (e) {
navigate("/login");
}
}
useEffect(() => {
init();
}, [])
在我的 todolist.tsx 中,我使用这样的 authStata :
const authStateValue = useRecoilValue(authState);
并且在我刷新并重新加载页面之前用户名不会更新,获取的待办事项是更新的,但在页面重新加载之前用户名不会更新
return (
<div>
<div style={{ display: "flex" }}>
<h2>Welcome {authStateValue.username}</h2>
<div style={{ marginTop: 25, marginLeft: 20 }}>
<button onClick={() => {
localStorage.removeItem("token");
navigate("/login");
}}>Logout</button>
</div>
</div>
<h2>Todo List</h2>
<input type="text" value={title} onChange={(e) => setTitle(e.target.value)} placeholder="Title" />
<input type="text" value={description} onChange={(e) => setDescription(e.target.value)} placeholder="Description" />
<button onClick={addTodo}>Add a new Todo</button>
{todos.map((todo) => (
<div key={todo._id}>
<h3>{todo.title}</h3>
<p>{todo.description}</p>
<button onClick={() => markDone(todo._id)} >{todo.done ? 'Done' : 'Mark as Done'}</button>
</div>
))}
</div>
)
};
export default TodoList
用户名也应该随着 todolist 组件重新渲染而更新,但除了用户名之外,所有正在获取的内容都显示良好。我不明白这个问题,我刚刚开始使用带有反冲力的打字稿
您似乎忘记在注销时重置您的
authState
原子。这会导致atom与localStorage不同步,并显示未登录的用户名。