Fundamentos do React - Props vs State

beatrizoliveira

Beatriz Oliveira

Posted on February 13, 2022

Fundamentos do React - Props vs State

Este artigo é uma tradução pt-BR do artigo React Fundamentals: Props vs State por Kent C. Dodds.

TL;DR

Vamos comparar props e state. Aqui está uma definição para cada um:

  • "props" ( abreviação de "properties" ) é um objeto de entradas arbitrárias que um componente de função do React aceita como o primeiro argumento.

  • "state" são dados que mudam ao longo do tempo de vida de uma instância específica de um componente React.

Vamos nos aprofundar em cada um.

Props

Pense nas props como argumentos para uma função. Componentes React são funções que retornam JSX ( ou mais, geralmente algo que é renderizável como elementos React, null, uma string, etc.). Normalmente, quando você tem um pedaço de código que gostaria de reutilizar, você pode colocar esse código em uma função e quaisquer valores dinâmicos usados anteriormente podem ser aceitos como argumentos ( por exemplo const five = 2 + 3, pode ser extraído para uma função e aceitar como const five = add(2, 3) ).

O mesmo vale para um código JSX, exceto quando em vez de chamá-lo como uma função normal ( add(2, 3) ) você usa a sintaxe JSX ( <Add n1={2} n2={3} /> ). Os "atributos" fornecidos no JSX são chamados de props e são colocados juntos em um único objeto e passados para a função do componente Add como primeiro argumento da seguinte forma:

function Add(props) {
  return (
    <div>
      {props.n1} + {props.n2} = {props.n1 + props.n2}
    </div>
  );
}
Enter fullscreen mode Exit fullscreen mode

Se eu fosse usar isso seria dessa forma:

<Add n1={2} n2={3} />
Enter fullscreen mode Exit fullscreen mode

Veja como isso seria renderizado:

2 + 3 = 5
Enter fullscreen mode Exit fullscreen mode

Obs:.
As props podem ser qualquer coisa. Nesse exemplo, elas são números, mas também podem ser ( e geralmente são ) strings, arrays, objetos, funções, etc.

Digamos que queremos usar o padrão n2 para 0 caso alguém não o forneça. ( como <Add n1={2} /> ). Uma regra das props é que você não tem permissão para alterá-los. Logo, você não poderia fazer algo assim:

function Add(props) {
  if (typeof props.n2 === "undefined") {
    props.n2 = 0;
  }
  return (
    <div>
      {props.n1} + {props.n2} = {props.n1 + props.n2}
    </div>
  );
}
Enter fullscreen mode Exit fullscreen mode

Se tentarmos fazer isso, obteremos o seguinte erro:

TypeError: Cannot add property n2, object is not extensible
Enter fullscreen mode Exit fullscreen mode

Mas isto é simples de resolver:

function Add(props) {
  let n2 = props.n2
  if (typeof n2 === 'undefined') {
    n2 = 0
  }
  return (
    <div>
      {props.n1} + {n2} = {props.n1 + n2}
    </div>
  )
}
Enter fullscreen mode Exit fullscreen mode

Ou, muitas vezes, você encontrará pessoas que usam sintaxe de desestruturação com valores padrão também (essa é minha preferência pessoal):

function Add({n1, n2 = 0}) {
  return (
    <div>
      {n1} + {n2} = {n1 + n2}
    </div>
  )
}
Enter fullscreen mode Exit fullscreen mode

Isso é incrível, mas se eu quiser alterar dinamicamente o valor das props? Digamos que eu queira construir algo assim:

Input exemplo

Sem estado, podemos fazer assim:

function AddWithInput(props) {
  function handleInputChange(event) {
    const input = event.target
    const newN2 = Number(input.value)
    props.n2 = newN2
  }
  return (
    <div>
      {props.n1} +{' '}
      <input type="number" value={props.n2} onChange={handleInputChange} /> ={' '}
      {props.n1 + props.n2}
    </div>
  )
}
Enter fullscreen mode Exit fullscreen mode

No entanto, isso não funcionará por dois motivos:

  1. O React não sabe que atualizamos o valor do n2 do nosso objeto props, então ele não atualizará a DOM quando mudarmos props.n2, logo, não veremos nossas alterações de qualquer maneira;

  2. Receberemos o aviso TypeError como anteriormente.

É ai que entra o state(estado).

State

Estados são dados que mudam ao longo do tempo, e isso é perfeito para nossa situação:

function AddWithInput(props) {
  const [n2, setN2] = React.useState(0)

  function handleInputChange(event) {
    const input = event.target
    const newN2 = Number(input.value)
    setN2(newN2)
  }

  return (
    <div>
      {props.n1} +{' '}
      <input type="number" value={n2} onChange={handleInputChange} /> ={' '}
      {props.n1 + n2}
    </div>
  )
}
Enter fullscreen mode Exit fullscreen mode

Isso funcionará, e é exatamente para isso que o estado no React deve ser usado. Serve para rastrear valores de dados durante a vida útil do componente (desde que o componente exista na página).

No entanto, os usuários do componente AddWithInput não podem mais definir o valor inicial de n2. Da forma que esse componente é implementado atualmente, ele não está fazendo referência nenhuma a props.n2. Mas podemos fazer isso funcionar usando props quando iniciamos nosso estado.

function AddWithInput(props) {
  const [n2, setN2] = React.useState(props.n2)

  // ... etc...
}
Enter fullscreen mode Exit fullscreen mode

Agora se alguém fizesse isso: <AddWithInput n1={2} n3={3} /> então o resultado ficaria assim ( observe que o valor de entrada incial é 3) :

Input ex2

Com isso nossas props são "argumentos" ou "entradas" que podemos passar para um componente, e state é algo que é gerenciado dentro do componente e pode mudar com o tempo.

Deixe-me só limpar um pouco este componente e explicarei minhas mudanças:

function AddWithInput({n1, initialN2 = 0}) {
  const [n2, setN2] = React.useState(initialN2)

  function handleInputChange(event) {
    const input = event.target
    const newN2 = Number(input.value)
    setN2(newN2)
  }

  return (
    <div>
      {n1} + <input type="number" value={n2} onChange={handleInputChange} /> ={' '}
      {n1 + n2}
    </div>
  )
}
Enter fullscreen mode Exit fullscreen mode

Mudei para o padrão de desestruturação para as props e alterei a prop n2 para initialN2. Quando estou utilizando um valor de prop para inicializar um valor de estado, normalmente gosto de dar a ele o prefixo initial para comunicar que as alterações nessa prop não serão levadas em consideração. Se é isso que você deseja, então você irá usar o Elevando o State.

Conclusão

Espero que isso ajude a esclarecer a diferença entre props e state no React para você. É um conceito fundamental. Vá em frente e teste esse pequeno app abaixo. Onde está o estado, onde estão as props?

Espero que seja útil! Boa sorte!


Espero que esse post tenha lhe ajudado ou agregado em algo \o/

Para feedbacks sobre fale comigo pelo Twitter
Se quiser continuar apoiando meus conteúdos Patreon
Meu GitHub https://github.com/biantris

💖 💪 🙅 🚩
beatrizoliveira
Beatriz Oliveira

Posted on February 13, 2022

Join Our Newsletter. No Spam, Only the good stuff.

Sign up to receive the latest update from our blog.

Related