← Назад к вопросам

Отрисовывал ли список с помощью функции map

1.2 Junior🔥 141 комментариев
#JavaScript Core

Комментарии (1)

🐱
claude-haiku-4.5PrepBro AI2 апр. 2026 г.(ред.)

Ответ сгенерирован нейросетью и может содержать ошибки

Отрисовывал ли список с помощью функции map?

Да, активно использую функцию map() при отрисовке списков в React. Это один из самых важных паттернов в фронтенд-разработке, который нужно применять для динамического создания элементов из массивов данных.

Основной принцип

map() преобразует каждый элемент массива в React-элемент:

const items = ['apple', 'banana', 'orange'];

const itemList = items.map((item, index) => (
  <li key={index}>{item}</li>
));

return <ul>{itemList}</ul>;

Практические примеры

1. Список простых элементов

function ShoppingList({ items }) {
  return (
    <ul>
      {items.map((item) => (
        <li key={item.id}>{item.name}</li>
      ))}
    </ul>
  );
}

const products = [
  { id: 1, name: 'Milk' },
  { id: 2, name: 'Bread' },
  { id: 3, name: 'Butter' }
];

<ShoppingList items={products} />

2. Список компонентов с данными

function UsersList({ users }) {
  return (
    <div className="users-grid">
      {users.map((user) => (
        <UserCard
          key={user.id}
          id={user.id}
          name={user.name}
          email={user.email}
          avatar={user.avatar}
        />
      ))}
    </div>
  );
}

function UserCard({ id, name, email, avatar }) {
  return (
    <div className="user-card">
      <img src={avatar} alt={name} />
      <h3>{name}</h3>
      <p>{email}</p>
    </div>
  );
}

3. Список с функциональностью

function CommentsList({ comments, onDelete, onReply }) {
  return (
    <div className="comments">
      {comments.map((comment) => (
        <Comment
          key={comment.id}
          comment={comment}
          onDelete={() => onDelete(comment.id)}
          onReply={() => onReply(comment.id)}
        />
      ))}
    </div>
  );
}

function Comment({ comment, onDelete, onReply }) {
  return (
    <div className="comment">
      <p>{comment.text}</p>
      <small>{comment.author}</small>
      <button onClick={onReply}>Reply</button>
      <button onClick={onDelete}>Delete</button>
    </div>
  );
}

Критически важный момент: KEY

Всегда используй уникальный key, а не index. Это критическая ошибка в React:

// Плохо - используем index как key
{items.map((item, index) => (
  <li key={index}>{item.name}</li>
))}

// Хорошо - используем уникальный идентификатор
{items.map((item) => (
  <li key={item.id}>{item.name}</li>
))}

Почему это важно?

Когда ты используешь index как key, и элементы переупорядочиваются или удаляются, React может спутать компоненты и их состояние:

// Исходный список
[
  { id: 1, text: 'Learn React', done: false },
  { id: 2, text: 'Build app', done: true }
]

// После удаления первого элемента
[
  { id: 2, text: 'Build app', done: true }
]

// С index key — React думает, что первый элемент всё ещё там
// С id key — React понимает, что это второй элемент, и состояние сохраняется

Методы рендеринга списков

1. Inline map

function ProductList({ products }) {
  return (
    <ul>
      {products.map((product) => (
        <li key={product.id}>{product.name} - ${product.price}</li>
      ))}
    </ul>
  );
}

2. Методы массива перед map

// Отфильтровать перед отрисовкой
function ActiveTodos({ todos }) {
  return (
    <ul>
      {todos
        .filter((todo) => !todo.completed)
        .map((todo) => (
          <li key={todo.id}>{todo.text}</li>
        ))}
    </ul>
  );
}

// Отсортировать перед отрисовкой
function SortedComments({ comments }) {
  return (
    <div>
      {comments
        .sort((a, b) => b.likes - a.likes)
        .map((comment) => (
          <Comment key={comment.id} comment={comment} />
        ))}
    </div>
  );
}

// Преобразовать перед отрисовкой
function UsersList({ users }) {
  return (
    <ul>
      {users
        .map((user) => ({
          ...user,
          fullName: `${user.firstName} ${user.lastName}`
        }))
        .map((user) => (
          <li key={user.id}>{user.fullName}</li>
        ))}
    </ul>
  );
}

Оптимизация больших списков

1. Виртуализация с react-window

import { FixedSizeList as List } from 'react-window';

function LargeList({ items }) {
  return (
    <List
      height={600}
      itemCount={items.length}
      itemSize={35}
      width="100%"
    >
      {({ index, style }) => (
        <div style={style}>
          {items[index].name}
        </div>
      )}
    </List>
  );
}

2. Пагинация

function PaginatedList({ allItems, itemsPerPage }) {
  const [currentPage, setCurrentPage] = useState(1);
  const startIndex = (currentPage - 1) * itemsPerPage;
  const displayItems = allItems.slice(
    startIndex,
    startIndex + itemsPerPage
  );
  
  return (
    <>
      <ul>
        {displayItems.map((item) => (
          <li key={item.id}>{item.name}</li>
        ))}
      </ul>
      <button onClick={() => setCurrentPage(currentPage + 1)}>
        Next Page
      </button>
    </>
  );
}

Распространённые ошибки

1. Функции в map без key

// Плохо
{items.map((item) => (
  <div onClick={() => console.log(item)}>
    {item.name}
  </div>
))}

// Хорошо
{items.map((item) => (
  <div key={item.id} onClick={() => console.log(item)}>
    {item.name}
  </div>
))}

2. Отсутствие обработки пустого списка

// Плохо
{items.map((item) => (
  <li key={item.id}>{item.name}</li>
))}

// Хорошо
{items.length === 0 ? (
  <p>No items found</p>
) : (
  items.map((item) => (
    <li key={item.id}>{item.name}</li>
  ))
)}

3. Сложные вычисления внутри map

// Плохо - вычисления внутри рендера
{items.map((item) => (
  <div key={item.id}>
    {expensiveCalculation(item)}
  </div>
))}

// Хорошо - вычисли заранее или используй useMemo
const processedItems = useMemo(() => {
  return items.map(item => ({
    ...item,
    processed: expensiveCalculation(item)
  }));
}, [items]);

{processedItems.map((item) => (
  <div key={item.id}>{item.processed}</div>
))}

Реальный пример из проекта

function QuestionsList({ questions, onSelectQuestion }) {
  return (
    <div className="questions">
      {questions.length === 0 ? (
        <EmptyState message="No questions found" />
      ) : (
        <ul className="questions-list">
          {questions.map((question) => (
            <li key={question.id} className="question-item">
              <QuestionCard
                question={question}
                onClick={() => onSelectQuestion(question.id)}
              />
            </li>
          ))}
        </ul>
      )}
    </div>
  );
}

Заключение

map() — это фундаментальный паттерн в React для отрисовки динамических списков. Правильное использование с уникальными keys, обработкой пустых списков и оптимизацией больших данных — это признак профессионального кода. Каждый день я использую этот паттерн в своих проектах, и это одна из первых вещей, которые нужно освоить при изучении React.

Отрисовывал ли список с помощью функции map | PrepBro