Isso aqui eu não aprendi bem hoje mas sim na semana passada na Next Level Week da Rocketseat. Funciona como uma alternativa a ter aqueles milhares de handle change para cada um dos inputs do formulário.

Passo 1. Ao invés de fazer um estado para cada campo do formulário você cria um estado com um objeto, contendo os campos do formulário que você está fazendo.

const [formData, setFormData] = useState({
    name: '',
    email: '',
    whatsapp: '',
    number: ''
})

Passo 2. Crie os seus inputs com os names iguais aos campos do objeto que você cadastrou no estado.

<input type="text" name="name" />
<input type="text" name="email" />
<input type="text" name="whatsapp" />
<input type="text" name="number" />

Passo 3. Agora vem a mágica. Na função de handle do inputvocê vai usar o nome para sobreescrever o campo no estado usando o spread operator ....

function handleInputChange(e) {
    setFormData({ ...formData, [e.target.name]: e.target.value })
}

Passo 4. E por fim passe a função no onChange dos inputs.

<input type="text" name="name" onChange={handleInputChange)/>
<input type="text" name="email" onChange={handleInputChange)/>
<input type="text" name="whatsapp" onChange={handleInputChange)/>
<input type="text" name="number" onChange={handleInputChange)/>

E pronto um código estremamente simples para lidar com mudanças de estado em um formulário.