Fundamentos do React - Props vs State
Beatriz Oliveira
Posted on February 13, 2022
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>
);
}
Se eu fosse usar isso seria dessa forma:
<Add n1={2} n2={3} />
Veja como isso seria renderizado:
2 + 3 = 5
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>
);
}
Se tentarmos fazer isso, obteremos o seguinte erro:
TypeError: Cannot add property n2, object is not extensible
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>
)
}
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>
)
}
Isso é incrível, mas se eu quiser alterar dinamicamente o valor das props? Digamos que eu queira construir algo assim:
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>
)
}
No entanto, isso não funcionará por dois motivos:
O React não sabe que atualizamos o valor do
n2
do nosso objetoprops
, então ele não atualizará a DOM quando mudarmosprops.n2
, logo, não veremos nossas alterações de qualquer maneira;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>
)
}
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...
}
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
) :
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>
)
}
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
Posted on February 13, 2022
Join Our Newsletter. No Spam, Only the good stuff.
Sign up to receive the latest update from our blog.