React Hooks: Não é mágica, apenas arrays

Com diagramas para explicar as regras dessa nova abordagem

Image for post
Image for post
Não existe mágica, são apenas arrays! — Créditos imagem

Entendendo como Hooks funcionam

As regras dos Hooks

Arrays, arrays e arrays! Gerenciamento de estado em Hooks é tudo sobre arrays!

Como poderíamos implementar useState()?

function RenderFunctionComponent() {
const [firstName, setFirstName] = useState("Rudi");
const [lastName, setLastName] = useState("Yardley");
return (
<Button onClick={() => setFirstName("Fred")}>Fred</Button>
);
}

Então, o que o React fará com isso?

1) Inicialização

Inicialização: Duas matrizes vazias, Cursor é 0
Inicialização: Duas matrizes vazias, Cursor é 0

2) Primeira renderização

Primeira renderização: Itens gravados nos arrays como incrementos do cursor.
Primeira renderização: Itens gravados nos arrays como incrementos do cursor.

3) Renderização subseqüente

Renderização subseqüente: itens lidos do array como incrementos de cursor
Renderização subseqüente: itens lidos do array como incrementos de cursor

4) Manipulação de eventos

Os setters “lembram” o seu índice e ajustam a memória de acordo com ele.
Os setters “lembram” o seu índice e ajustam a memória de acordo com ele.

E nossa implementação ingênua…

let state = [];
let setters = [];
let firstRun = true;
let cursor = 0;
function createSetter(cursor) {
return function setterWithCursor(newVal) {
state[cursor] = newVal;
};
}
// Pseudo-código para uma função `useState`
export function useState(initVal) {
if (firstRun) {
state.push(initVal);
setters.push(createSetter(cursor));
firstRun = false;
}
const setter = setters[cursor];
const value = state[cursor];
cursor++;
return [value, setter];
}
// Um exemplo de componente usando Hooks
function RenderFunctionComponent() {
const [firstName, setFirstName] = useState("Rudi"); // cursor: 0
const [lastName, setLastName] = useState("Yardley"); // cursor: 1
return (
<div>
<Button onClick={() => setFirstName("Richard")}>Richard</Button>
<Button onClick={() => setFirstName("Fred")}>Fred</Button>
</div>
);
}
// Uma espécie de simulação do ciclo de renderização do React
function MyComponent() {
cursor = 0; // redefinindo o cursor
return <RenderFunctionComponent />; // render
}
console.log(state); // Pré-renderização: []
MyComponent();
console.log(state); // Primeira renderização: ['Rudi', 'Yardley']
MyComponent();
console.log(state); // Renderizações subsequentes: ['Rudi', 'Yardley']
// clique no botão 'Fred'console.log(state); // Estado após o evento `click`: ['Fred', 'Yardley']

Por que a ordem é importante?

let firstRender = true;function RenderFunctionComponent() {
let initName;

if(firstRender){
[initName] = useState("Rudi");
firstRender = false;
}
const [firstName, setFirstName] = useState(initName);
const [lastName, setLastName] = useState("Yardley");
return (
<Button onClick={() => setFirstName("Fred")}>Fred</Button>
);
}

Primeira renderização ruim para o componente

Renderizando um Hook extra 'ruim' que será eliminado na próxima renderização
Renderizando um Hook extra ‘ruim’ que será eliminado na próxima renderização

Renderizações subsequentes são piores

Ao remover o gancho entre os processos de renderização, obtemos um erro.
Ao remover o hook entre os processos de renderização, obtemos um erro.

Pense em Hooks como uma manipulação de um conjunto de arrays, e você não quebrará as regras!

Conclusão

⭐️ Créditos

Written by

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store