React converts elements to lists

A map-like approach

const numbers = [1.2.3.4.5];
const doubled = numbers.map((number) = > number * 2);
console.log(doubled);
Copy the code

Render multiple components

Change each element in the array to a LI tag

const numbers = [1.2.3.4.5];
const listItems = numbers.map((number) = >
  <li>{number}</li>
);
Copy the code

Insert the entire listItems into the <ul> element and render it into the DOM:

ReactDOM.render(
  <ul>{listItems}</ul>.document.getElementById('root'));Copy the code

Base list component

  • Extract the example described above into a component
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'));Copy the code

Official description: When we run this code, we will see a warning that a key should be provided for list items, meaning that when you create an element, you must include a special key property.

Solve the warning

Assign a key attribute to each list element

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'));Copy the code

Key

Why add a key attribute to every Li element?

The key helps React identify which elements have changed, such as being added or removed.

Interpretation of the

React updates the DOM using the Diffing algorithm. Only elements that have changed will update the DOM. If React uses the key attribute, it can tell which Li element has changed.

  • An element’s key should ideally be a unique string that the element has in the list. Typically, we use the ID in the data as the element’s key.
const todoItems = todos.map((todo) = >
  <li key={todo.id}>
    {todo.text}
  </li>
);
Copy the code
  • As a last resort, you can use the element index as the key when the element has no specified ID
const todoItems = todos.map((todo, index) = >
  // Only do this if items have no stable IDs
  <li key={index}>
    {todo.text}
  </li>
);
Copy the code

Why not recommend indexing as the key attribute

Official description: We do not recommend using an index as a key if the order of list items may change, as this can lead to poor performance and may cause component state issues. Check out Robin Pokorny’s in-depth analysis of the negative effects of using indexes as keys. If you choose not to specify an explicit key, React will default to using the index as the key for list items.

Interpretation of the

Using an index as a key property can cause unexpected errors if the order of array elements changes, so React is not recommended.

Extract components with keys

Official description: Element keys only make sense in the context of the nearest array. For example, if you extract a ListItem component, you should leave the key on that element in the array, not on the <li> element in the ListItem component.

Example: Incorrect use of key

function ListItem(props) {
  const value = props.value;
  return (
    / / error! You don't need to specify key here:
    <li key={value.toString()}>
      {value}
    </li>
  );
}

function NumberList(props) {
  const numbers = props.numbers;
  const listItems = numbers.map((number) = >
    / / error! The element's key should be specified here:
    <ListItem value={number} />
  );
  return (
    <ul>
      {listItems}
    </ul>
  );
}

const numbers = [1.2.3.4.5];
ReactDOM.render(
  <NumberList numbers={numbers} />.document.getElementById('root'));Copy the code

Example: The correct way to use key

function ListItem(props) {
  / / right! There is no need to specify key:
  return <li>{props.value}</li>;
}

function NumberList(props) {
  const numbers = props.numbers;
  const listItems = numbers.map((number) = >
    / / right! The key should be specified in the context of 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'));Copy the code

Official tips

Elements in the map() method require a key attribute.

The key must only be unique between sibling nodes

Official description: A key used in an array element should be unique among its siblings. However, they need not be globally unique. When we generate two different arrays, we can use the same key.

The key will pass information to React, but not to your components. If you need the value of the key attribute in your component, pass it explicitly with another attribute name:

const content = posts.map((post) = >
  <Post
    key={post.id}
    id={post.id}
    title={post.title} />
);
Copy the code

In the example above, the Post component can read props. Id, but not props. Key, so we must pay attention to this

Embed map() in JSX

JSX allows any expression to be embedded in braces, so we can inline the result returned by map() :

This article gains a lot, the close reading official document gains a lot, cleared up some knowledge blind spot. Please follow my column and learn the React documentation.