43
loading...
This website collects cookies to deliver better user experience
The current state will always be the current state after it has been changed, just like you have in useState.
The dispatch function is the state updating function, almost like useState, but here, the dispatch function returns an action which is an object with a type and a payload. The action type helps the reducer to know the function that is updating the state and the payload is the value that needs to be updated.
The reducer function receives the latest state and the action that the dispatch function sent and then returns a new updated state
The initial state is the very first state you seed your useReducer hook with.
The initial function is rarely used, but it's a function you use to set your initial state.
import React, {useReducer} from "react";
const reducerFxn = (state, action) => {
}
const initialState = {
enteredEmail : "",
emailIsValid : null,
enteredPassword: "",
passwordIsValid : null
}
const Login = () => {
const [currentState, dispatchFxn] = useReducer(reducerFxn, initialState);
const emailChangeHandler = (e) => {
dispatchFxn({
type:'ADD_EMAIL',
payload: e.target.value
})
}
const passwordChangeHandler = (e) => {
dispatchFxn({
type:'ADD_PASS',
payload: e.target.value
})
}
return <form>
<div>
<label htmlFor="email">E-Mail</label>
<input type="email" id="email"
value={state.enteredEmail}
onChange={emailChangeHandler} />
</div>
<div>
<label htmlFor="password">Password</label>
<input type="password" id="password"
value={state.enteredPassword}
onChange={passwordChangeHandler} />
</div>
</form>
}
export default Login
import React, { useReducer } from "react";
const reducerFxn = (state, action) => {
if (action.type === "ADD_EMAIL") {
return {
enteredEmail: action.payload,
emailIsValid: action.payload.includes("@"),
enteredPassword: state.enteredPassword,
passwordIsValid: state.passwordIsValid,
};
}
if (action.type === "ADD_PASS") {
return {
enteredEmail: state.enteredEmail,
emailIsValid: state.emailIsValid,
enteredPassword: action.payload,
passwordIsValid: action.payload.trim().length >= 6,
};
}
return state;
};
const initialState = {
enteredEmail: "",
emailIsValid: null,
enteredPassword: "",
passwordIsValid: null,
};
const Login = () => {
const [currentState, dispatchFxn] = useReducer(reducerFxn, initialState);
const emailChangeHandler = (e) => {
dispatchFxn({
type: "ADD_EMAIL",
payload: e.target.value,
});
};
const passwordChangeHandler = (e) => {
dispatchFxn({
type: "ADD_PASS",
payload: e.target.value,
});
};
const submitHandler = (e) => {
e.preventDefault();
console.log(currentState);
};
return (
<form onSubmit={submitHandler}>
<div>
<label htmlFor="email">E-Mail</label>
<input
type="email"
id="email"
value={currentState.enteredEmail}
onChange={emailChangeHandler}
/>
</div>
<div>
<label htmlFor="password">Password</label>
<input
type="password"
id="password"
value={currentState.enteredPassword}
onChange={passwordChangeHandler}
/>
</div>
<button>Submit</button>
</form>
);
};
export default Login;
Remember i told you that, reducerfxn takes in 2 values, the current state and the action(which contains what the dispatch function dispatched).
It checks for the type of dispatch and changes the state according to who sent it, in the case of the email, it checked it with if(action.type === 'ADD_EMAIL') block which returns true and it corresponds with what we dispatched and it will change the state with the payload as you have seen.
The enteredEmail field is updated with the action.payload which is equal to the event.target.value that we dispatched, now this is where useReducer is powerful, we now updated the emaiIsValid field instantly by checking if the payload contains '@' and this will return true or false. This saves us the extra stress of creating another useState hook if we wanted to update the state with useState.