Primeiro, rever como revisar como você transforma listas em JavaScript.
Dado o código abaixo, usamos a função map()
para pegar um array de numbers
e dobrar seus valores. Nós atribuímos o novo array retornado por map()
a variável doubled
e depois exibimos no log:
const numbers = [1, 2, 3, 4, 5];
const doubled = numbers.map((number) => number * 2);
console.log(doubled);
O código irá imprimir [2, 4, 6, 8, 10]
no log do console.
Em React, transformar arrys em listas de elements é quase idêntico.
Você pode criar coleções de elementos e incluí-los em JSX usando chaves {}
.
Abaixo, nós percorremos pelo array numbers
usando a função Javascript map()
. Nós retornamos um elemento <li>
para cada item. Finalmente, nós atribuímos o array resultante de elementos a constante listItems
:
const numbers = [1, 2, 3, 4, 5];
const listItems = numbers.map((number) =>
<li>{number}</li>
);
Nós incluímos todo o array listItems
dentro de um elemento <ul>
, e renderizamos no DOM:
ReactDOM.render(
<ul>{listItems}</ul>,
document.getElementById('root')
);
Este código exibe uma lista de números entre 1 e 5.
Geralmente você renderiza listas dentro de um componente.
Nós podemos refatorar o exemplo anterior em um componente que aceita um array de numbers
e imprime uma lista não ordenada de elementos.
function NumberList(props) {
const numbers = props.numbers;
const listItems = numbers.map((number) =>
<li>{number}</li>
);
return (
<ul>{listItems}</ul>
);
}
const numbers = [1, 2, 3, 4, 5];
ReactDOM.render(
<NumberList numbers={numbers} />,
document.getElementById('root')
);
Quando você executar este código, você receberá um aviso que uma chave deve ser informada para os itens da lista. Uma "key" (chave) é um atributo string especial que você deve incluir quando cria listas de elementos. Nós iremos discutir porque é importante na próxima seção.
Vamos atribuir uma key
(chave) para nossos itens dentro de numbers.map()
e consertar o problema de chave não existente.
function NumberList(props) {
const numbers = props.numbers;
const listItems = numbers.map((number) =>
<li key={number.toString()}>
{number}
</li>
);
return (
<ul>{listItems}</ul>
);
}
const numbers = [1, 2, 3, 4, 5];
ReactDOM.render(
<NumberList numbers={numbers} />,
document.getElementById('root')
);
Chages ajudam o React a identificar quais itens mudaram, são adicionados, ou são removidos. Chaves devem ser dadas aos elementos dentro do array para fornecer uma identidade estável para os elementos:
const numbers = [1, 2, 3, 4, 5];
const listItems = numbers.map((number) =>
<li key={number.toString()}>
{number}
</li>
);
A melhor maneira de escolher uma chave é umsar uma string que identifica exclusivamente um item da lista em relação a seus irmãos. Na maioria das vezes você usa IDs de seus dados como chaves:
const todoItems = todos.map((todo) =>
<li key={todo.id}>
{todo.text}
</li>
);
Quando você não tem IDs estáves para renderizar os itens, você deve usar o índice do item como uma chave como último recurso:
const todoItems = todos.map((todo, index) =>
// Only do this if items have no stable IDs
<li key={index}>
{todo.text}
</li>
);
Nós não recomendamos usar índices para chaves se os itens podem ser reordenados, pois isso seria lento. Você pode ler um explicação detalhada sobre porque chaves são necessárias se estiver interessado.
Chaves só fazem sentido no contexto de arrays.
Por exemplo, se você extrair um componente ListItem
, você deve manter a chave nos elementos <ListItem />
no array ao invés na raiz do elemento <li>
dentro de ListItem
em si.
Exemplo: Uso incorreto de chave(key)
function ListItem(props) {
const value = props.value;
return (
// Wrong! There is no need to specify the key here:
<li key={value.toString()}>
{value}
</li>
);
}
function NumberList(props) {
const numbers = props.numbers;
const listItems = numbers.map((number) =>
// Wrong! The key should have been specified here:
<ListItem value={number} />
);
return (
<ul>
{listItems}
</ul>
);
}
const numbers = [1, 2, 3, 4, 5];
ReactDOM.render(
<NumberList numbers={numbers} />,
document.getElementById('root')
);
Examplo: Uso correto de chave(key)
function ListItem(props) {
// Correct! There is no need to specify the key here:
return <li>{props.value}</li>;
}
function NumberList(props) {
const numbers = props.numbers;
const listItems = numbers.map((number) =>
// Correct! Key should be specified inside the array.
<ListItem key={number.toString()}
value={number} />
);
return (
<ul>
{listItems}
</ul>
);
}
const numbers = [1, 2, 3, 4, 5];
ReactDOM.render(
<NumberList numbers={numbers} />,
document.getElementById('root')
);
Uma regra de ouro é que elementos dentro de map()
devem ter chaves(keys).
Chaves usadas dentro de arrays devem ser únicas entre seus irmãos. No entanto, elas não devem ser únicas globalmente. Nós podemos usar a mesma chave para criar dois arrays diferentes:
function Blog(props) {
const sidebar = (
<ul>
{props.posts.map((post) =>
<li key={post.id}>
{post.title}
</li>
)}
</ul>
);
const content = props.posts.map((post) =>
<div key={post.id}>
<h3>{post.title}</h3>
<p>{post.content}</p>
</div>
);
return (
<div>
{sidebar}
<hr />
{content}
</div>
);
}
const posts = [
{id: 1, title: 'Hello World', content: 'Welcome to learning React!'},
{id: 2, title: 'Installation', content: 'You can install React from npm.'}
];
ReactDOM.render(
<Blog posts={posts} />,
document.getElementById('root')
);
Chaves servem como uma dica para o React, mas elas não passam para seus componentes. Se você precisar do mesmo valor no seu componente, passe-o explicitamente como uma propriedade com um nome diferente:
const content = posts.map((post) =>
<Post
key={post.id}
id={post.id}
title={post.title} />
);
Com o exemplo acima, o componente Post
pode ler props.id
, mas não props.key
.
Nos exemplos acima nós declaramos uma variável listItems
separada e incluímos no JSX:
function NumberList(props) {
const numbers = props.numbers;
const listItems = numbers.map((number) =>
<ListItem key={number.toString()}
value={number} />
);
return (
<ul>
{listItems}
</ul>
);
}
JSX permite incorporar qualquer expressão entre chaves, então nós podemos chamar a função map()
diretamente, veja o resultado:
function NumberList(props) {
const numbers = props.numbers;
return (
<ul>
{numbers.map((number) =>
<ListItem key={number.toString()}
value={number} />
)}
</ul>
);
}
As vezes isso resulta em um código mais claro, mas este estilo pode também ser abusado. Como no JavaScript, cabe a você decidir se vale a pena extrair uma variável para facilitar a leitura. Tenha em mente que se o corpo de map()
for muito aninhado, pode ser uma boa hora para extrair para um componente.