o useReducer é mais um Hook usado para gerenciar estados no nosso componente, mas com ele podemos centralizar a lógica que iremos aplicar ao estado do componente usando um reducer. Ao contrário do useState onde usamos uma função para mudar diretamente o estado do nosso componente, com o useReducer usamos Dispatchs para modificar o estado através de um reducer intermediário em que passamos actions como paramêtros para as modificações.
import React, { useReducer } from 'react';
// Criamos um valor inicial do nosso reducer
const initialInputState = {
value: '',
error: '',
validation: /^[a-zA-Z]*$/
};
// Definimos o reducer para executar o dispatch e
// sempre que chamarmos a action para modificar o valor
// validamos o input da action
const inputReducer = (state, action) => {
switch(action.type){
case 'change':
if(state.validation.test(action.value))
return {...state, value: action.value, error: ''}
else
return {...state, value: action.value, error: 'Invalid input'}
default:
return state;
}
};
function InputWithValidation() {
const [inputState, dispatch] = useReducer(inputReducer, initialInputState);
return (
<div>
{/*
Definimos o valor padrão do input e adicionamos
um dispatch para atualizar o valor
*/}
<input value={inputState.value} onChange={
(e) => dispatch({type: 'change', value: e.target.value}
)} />
<p>{inputState.error}</p>
</div>
);
}
Desse jeito conseguimos encapsular o comportamento do estado dentro de um reducer e gerenciar melhor a mudança de estados do componente. Mas é recomendado que o reducer seja uma função pura para que as actions tenham um efeito mais previsível.