So i’ve written the logic for a login functionality using RTK toolkit and these are the components. In the logic component, while calling on handle submit, i always get error to be empty the first time and then the second time it gets called, i get the actual state.
I do know that this is about JS closures and I should be handling the console.log using a useEffect but what if i need to call multiple async dispatch functions based on the outcome of login dispatch. How would i write code for this ?
For example, something like this :
function handleSubmit(e) {
e.preventDefault();
dispatch(login(email, password));
if (loginError) return;
dispatch(fetchCustomerProfile(id))
if(fetchError) return;
dispatch(hideModal("login")
}
This is how my code looks right now :
const Login = () => {
const [email, setEmail] = useState("");
const [password, setPassword] = useState("");
const dispatch = useDispatch();
const error = useSelector(getError);
function handleSubmit(e) {
e.preventDefault();
dispatch(login(email, password));
if (error) console.log("Const");
}
return (
<form
className="mt-4 flex flex-col m-[44px]"
onSubmit={(e) => handleSubmit(e)}
>
<FormInput
label="Email ID"
name="emailID"
type="text"
value={email}
setValue={setEmail}
/>
<FormInput
label="Password"
name="password"
type="password"
value={password}
setValue={setPassword}
className="mt-3"
/>
{error && <h3>Error Occuerd</h3>}
<Button
className="mt-6 ml-auto w-full bg-yellow-500 text-black"
name={"Login"}
/>
</form>
);
};
authSlice.js
const initialState = {
user: {},
error: "",
status: {},
};
const login = createAsyncThunk("auth/login", async ({ email, password }) => {
try {
const { payload: user } = await authAPI.login(email, password);
return user;
} catch (error) {
throw new Error(error.message);
}
});
const authSlice = createSlice({
name: "auth",
initialState,
extraReducers: (builder) =>
builder
.addCase(login.pending, (state) => {
state.status = "pending";
state.error = "";
})
.addCase(login.fulfilled, (state, { payload }) => {
state.status = "fullfilled";
state.error = "";
state.user = payload;
})
.addCase(login.rejected, (state, { error }) => {
state.status = "rejected";
state.error = error.message;
console.log(state.error);
}),
});
export default authSlice.reducer;
export const getError = (state) => state.auth.error;
export { login };