Async await在我的React项目上不能正常运行。它并没有等待回应。Redux状态在调用函数时显示前一个或默认值,但在函数之外,它工作得很好。如您所见,我在handlessubmit函数中打印了选择器中的雇员,但是这打印的是先前或默认状态,我需要更新后的值才能继续。未等待数据
// handle submit function
const handleSubmit = async(values) => {
const personalData = new FormData();
Object.keys(personalValue).forEach((key) => personalData.append(key, personalValue[key]));
await dispatch(addEmployeePersonal(personalData));
console.log(employee) // Inside the function Employee prints default or previous state value
};
console.log(employee) // Here it's working fine, Outside the function employee prints updated value
// Selector
const {
employee,
employeeLoading,
employeeError
} = useSelector((state) => state.employee);
// Redux Reducer
export const employeeReducer = (state = {
employee: 0
}, action) => {
switch (action.type) {
case UPDATE_EMPLOYEE_PERSONAL_REQUEST:
case EMPLOYEE_ID_REQUEST:
case NEW_EMPLOYEE_PERSONAL_REQUEST:
case NEW_EMPLOYEE_OFFICIAL_REQUEST:
case DELETE_EMPLOYEE_REQUEST:
return {
...state,
employeeLoading: true,
employee: 0,
};
case UPDATE_EMPLOYEE_PERSONAL_SUCCESS:
case UPDATE_EMPLOYEE_OFFICIAL_SUCCESS:
case EMPLOYEE_ID_SUCCESS:
case NEW_EMPLOYEE_PERSONAL_SUCCESS:
case NEW_EMPLOYEE_OFFICIAL_SUCCESS:
case DELETE_EMPLOYEE_SUCCESS:
return {
...state,
employeeLoading: false,
employee: action.payload,
};
case UPDATE_EMPLOYEE_PERSONAL_FAILED:
case UPDATE_EMPLOYEE_OFFICIAL_FAILED:
case EMPLOYEE_ID_FAILED:
case NEW_EMPLOYEE_PERSONAL_FAILED:
case NEW_EMPLOYEE_OFFICIAL_FAILED:
case DELETE_EMPLOYEE_FAILED:
return {
...state,
employeeLoading: false,
employeeError: action.payload,
};
case CLEAR_ERRORS:
return {
...state,
employeeError: null,
};
default:
return state;
}
};
// Redux Action
export const addEmployeePersonal = (info) => async(dispatch) => {
try {
dispatch({
type: NEW_EMPLOYEE_PERSONAL_REQUEST
});
const {
data
} = await coreAxios.post("/api/Employee/PersonalInfo", info);
dispatch({
type: NEW_EMPLOYEE_PERSONAL_SUCCESS,
payload: data,
});
} catch (error) {
dispatch({
type: NEW_EMPLOYEE_PERSONAL_FAILED,
payload: error.response,
});
}
};
原因:组件第一次渲染时,employee
值为0
。触发表单提交处理程序,它使用employee
,其值为0
。即使您调度一个动作并尝试更改它,handleSubmit
在完成执行之前仍然使用在组件的第一次呈现(函数组件的执行)中计算的employee
。。await dispatch(thunk())
不会等待组件的下一次渲染。这就是为什么你会得到employee
的前一个值。
在handleSubmit
完成其执行后,redux存储中的状态已经更改,redux存储上下文提供程序将订阅该更改并呈现子节点。您的组件将重新呈现(函数组件的第二次执行),useSelector
将再次执行并返回新的employee
。将声明一个新的handleSubmit
函数,它引用函数组件作用域中定义的新的employee
。
有两个解决方案:
选项1:useEffect
useEffect(() => {
// get the latest employee to do something.
}, [employee])
选项2:以thunk形式返回操作负载,以便在调度操作后获得它
export const addEmployeePersonal = (info) => async(dispatch) => {
try {
dispatch({
type: NEW_EMPLOYEE_PERSONAL_REQUEST
});
const {
data
} = await coreAxios.post("/api/Employee/PersonalInfo", info);
dispatch({
type: NEW_EMPLOYEE_PERSONAL_SUCCESS,
payload: data,
});
return data; // here
} catch (error) {
dispatch({
type: NEW_EMPLOYEE_PERSONAL_FAILED,
payload: error.response,
});
}
};
const handleSubmit = async(values) => {
const personalData = new FormData();
Object.keys(personalValue).forEach((key) => personalData.append(key, personalValue[key]));
const newEmployee = await dispatch(addEmployeePersonal(personalData));
// Do something with newEmployee.
};