尝试设置状态似乎无法立即更新状态,我不确定如何实现所需的结果。
const Settings = (props: Props) => {
const { user } = props;
const initState: State = {
newName: user.displayName,
newAvatarUrl: user.avatarUrl,
disabled: false,
};
const [form, setForm] = useState(initState);
const handleUploadFile = async () => {
const fileElement = document.getElementById('upload-file') as HTMLFormElement;
const file = fileElement.files[0];
if (file == null) {
return;
}
setForm({ ...form, disabled: true });
try {
const response = await asynFunc1()
await asyncFun2(response)
setForm({ ...form, newAvatarUrl: response.url });
await asyncFunc3(form.newAvatarUrl) // Expected: response.url Observed: old value
} catch (error) {
consol.log(error)
} finally {
setForm({ ...form, disabled: false });
}
};
return (
<h4>Your Avatar</h4>
<Avatar
src={form.newAvatarUrl}
style={{
display: 'inline-flex',
verticalAlign: 'middle',
marginRight: 20,
width: 60,
height: 60,
}}
/>
<label htmlFor="upload-file">
<Button variant="outlined" color="primary" component="span" disabled={form.disabled}>
Update Avatar
</Button>
</label>
<input
accept="image/*"
name="upload-file"
id="upload-file"
type="file"
style={{ display: 'none' }}
onChange={handleUploadFile}
/>
);
};
setForm似乎不是同步的,但是它没有返回promise,所以我不确定如何以同步方式使用它。
答案 0 :(得分:1)
如评论中所述,状态更新是异步的。相反,您应该只将response.url传递给asyncFunc3调用,并在成功返回后设置表单状态。会是这样的:
const Settings = (props: Props) => {
const { user } = props;
const initState: State = {
newName: user.displayName,
newAvatarUrl: user.avatarUrl,
disabled: false,
};
const [form, setForm] = useState(initState);
const handleUploadFile = async () => {
const fileElement = document.getElementById('upload-file') as HTMLFormElement;
const file = fileElement.files[0];
if (file == null) {
return;
}
setForm({ ...form, disabled: true });
try {
const response = await asynFunc1()
await asyncFun2(response)
await asyncFunc3(response.url)
setForm({ ...form, newAvatarUrl: response.url });
} catch (error) {
consol.log(error)
} finally {
setForm({ ...form, disabled: false });
}
};
return (
<h4>Your Avatar</h4>
<Avatar
src={form.newAvatarUrl}
style={{
display: 'inline-flex',
verticalAlign: 'middle',
marginRight: 20,
width: 60,
height: 60,
}}
/>
<label htmlFor="upload-file">
<Button variant="outlined" color="primary" component="span" disabled={form.disabled}>
Update Avatar
</Button>
</label>
<input
accept="image/*"
name="upload-file"
id="upload-file"
type="file"
style={{ display: 'none' }}
onChange={handleUploadFile}
/>
);
};