【发布时间】:2020-10-28 12:20:31
【问题描述】:
对于我的应用程序的注册表单,我使用本地组件状态维护表单值,但 currentUser 状态、错误状态和 API 调用都在 Redux 中。
我希望在提交表单时,按钮有一个加载微调器,并且表单值保持不变,直到服务器返回响应。如果服务器以授权用户响应,则重定向到应用程序。如果出现错误,则应不清除表单的值。
问题似乎是 Redux 在调度任何状态更新函数时清除了我的表单值(无论是删除错误还是进行 API 调用以授权用户)。有什么办法可以避免这种情况发生吗?
来自我的 AuthForm.js
const submitData = () => {
setLoading(true);
if (formType === 'reset') {
updatePassword(resetToken, values.password, history)
.then(result => setLoading(false));
} else if (formType === 'forgot') {
forgotPassword(values.email, history);
} else {
console.log(values); // form values still populated
onAuth(formType, values, history)
.then(result => {
console.log('result received'); // values empty
setLoading(false);
if (formType === 'signup') {
history.push('/questionnaire')
} else {
history.push('/app')
}
})
.catch(err => setLoading(false));
}
};
来自我的 redux actions.js 文件:
export function authUser(type, userData, history) {
return dispatch => {
dispatch(removeError());
console.log('dispatch') // by this time the form values are empty
// unless I comment out the dispatch(removeError()) above,
// in which case we still have values until 'token recevied' below
return apiCall('post', `/users/${type}`, userData)
.then(({ jwt, refresh_token, ...user }) => {
console.log('token received')
localStorage.setItem('jwtToken', jwt);
localStorage.setItem('jwtTokenRefresh', refresh_token);
dispatch(getUser(user.id));
})
.catch(err => {
handleError(dispatch, err);
});
};
}
编辑:看起来我的组件肯定正在卸载,但我仍然不清楚为什么,或者如何防止它。
我正在尝试记忆调度功能,但它似乎没有效果。
const dispatch = useDispatch();
const onAuth = useCallback(
(formType, values, history) => {
dispatch(authUser(formType, values, history))
},
[dispatch]
);
【问题讨论】:
-
您的表单值处于本地状态,因此我认为当您调度某些操作时组件已卸载。如果事件处理程序正在提交表单,你也应该防止默认。
-
有没有办法避免这种情况?这似乎是一个相当常见的用例,您希望保留本地状态但在 Redux 中更新某些内容。
-
我的 handleSubmit() 函数中也有 e.preventDefalut()
-
避免什么?如果状态重置是由组件重新安装引起的,那么您可以解除状态,将其放入 redux 或使用该状态的上下文。
-
避免重新安装组件——没有理由这样做。状态处于适当的级别,因为它指的是 AuthForm.js 工作的表单
标签: javascript reactjs redux