Migrando Class para Function component

Em algum momento de nossas vidas teremos de refatorar os Class Components que empurramos para debaixo do tapete. O objetivo deste artigo é te auxiliar nesse processo.

Chamarei o Class Component de CC e os Function Component de FC para facilitar única e exclusivamente a minha vida. Tá passada?

Com FC e hooks nós podemos cobrir todas as funcionalidades de um CC como:

  1. Para o state do CC, temos o useState hook
  2. CC ciclo de vida, temos o useEffect hook
  3. Bonus: melhor abstração com custom hooks (Falarei mais sobre isso no futuro)

Como você faria para refatorar o código abaixo usando hooks e FC?

class App extends React.Component {

  state = {
    value: localStorage.getItem("info") || ""
  };

  componentDidUpdate() {
    localStorage.setItem("info", this.state.value);
  }

  onChange = event => {
    this.setState({ value: event.target.value });
  };

  render() {
    const { value } = this.state;
    return (
      <div>
        <input value={value} type="text" onChange={this.onChange} />
        <p>{value}</p>
      </div>
    );
  }
}

Com certeza você já descobriu como fazer esse refactor, certo? Vou escrever abaixo o código que você pensou, só para deixar registrado.

const App = () => {
  const val = localStorage.getItem("info") || "";
  const [value, setValue] = useState(val);
  const onChange = event => setValue(event.target.value);

  useEffect(() => localStorage.setItem("info", value), [value]);

  return (
    <div>
      <input value={value} type="text" onChange={onChange} />
      <p>{value}</p>
    </div>
  );
};

Substituímos o setState pelo useState e o componentDidUpdate pelo useEffect. Diminuimos as linhas de código e mantivemos todas as funcionalidades!

Mas dá pra irmos além. Nosso objetivo é tornar o nosso código reutilizável para evitar o famoso retrabalho. Como podemos fazer isso? Por criarmos um custom hook

const usePersistentStorage = key => {
  const val = localStorage.getItem(key) || "";
  const [value, setValue] = useState(val);

  useEffect(() => localStorage.setItem(key, value), [key, value]);

  return [value, setValue];
};

Agora é só utilizarmos o hook usePersistentStorage no nosso App component.

const App = () => {
  const [value, setValue] = usePersistentStorage("info");

  const onChange = event => setValue(event.target.value);

  return (
    <div>
      <input value={value} type="text" onChange={onChange} />
      <p>{value}</p>
    </div>
  );
};

Agora temos apenas 10 linhas de código e ainda poderemos usar o usePersistentStorage em N lugares.

23