在钩子 setState 之后的下一行执行代码的后果是什么?



我提前为问一个经常讨论的问题道歉。我的问题不是关于如何正确编写代码,而是以不推荐的方式这样做的后果是什么。我不确定在功能组件中设置状态后立即执行代码是否可以接受。React 似乎可以很好地执行代码而不会抱怨,但是我看到的每篇帖子都建议在 useImpact 中编写后续代码。

请看这个片段:LoginPage.jsx

async function handleSubmit(e) {
e.preventDefault();
const user = await login({ username, password });
setUser(user);
// Why is this not recommended?
history.push('/profile');
}

user状态属于顶级组件App,并且必须定义它才能ProfilePage渲染而不会崩溃。user最初是undefined.

在此特定情况下,user状态将更新,然后浏览器将重定向到/profile,而不会出现任何可见问题。这似乎是同步发生的,因为ProfilePage渲染而不会崩溃。

上下文

function App() {
const [user, setUser] = useState(undefined);
return (
<Switch>
<Route path='/login'>
<LoginPage setUser={setUser} />
</Route>
<Route path='/profile'>
<ProfilePage user={user} />
</Route>
</Switch>
);
}
function ProfilePage({ user }) {
return <div>{user.username}</div>
}
function LoginPage({ setUser }) {
const [username, setUsername] = useState('');
const [password, setPassword] = useState('');
const history = useHistory();
function handleChangeUsername(e) {
setUsername(e.target.value);
}
function handleChangePassword(e) {
setPassword(e.target.value);
}
async function handleSubmit(e) {
e.preventDefault();
const user = await login({ username, password });
setUser(user);
history.push('/profile');
}
return (
<form onSubmit={handleSubmit}>
<input type="text" placeholder="username" value={username} onChange={handleChangeUsername} />
<input type="text" placeholder="password" value={password} onChange={handleChangePassword} />
<input type="submit" />
</form>
);
}

不建议这样做,因为useState挂钩会异步更新状态,并且在离开组件之前不能依赖更新的状态。如果组件中没有太多其他事情发生,并且浏览器不必等待I/O,那么您可能永远不会真正看到问题。但是,它可能会在以后绊倒您,并且需要您永远弄清楚,因为在那一刻之前它从未成为问题。

最好使用useEffect钩子遵循最佳实践。