Написать пост

ToDoList: Найди ошибку в JS-коде, фреймворк React

Аватарка пользователя Grigorii Sharapov

Компонент ToDoList принимает массив элементов и отображает их в виде списка. Найди ошибку в JavaScript-коде на React.

В этой части «Найди ошибку» компонент ToDoList, принимает массив элементов и отображает их в виде списка. Однако в коде есть небольшая ошибка:

			import React from "react";

const ToDoList = ({ items }) => {
  return (
    <div>
      <ul>
        {items.length && items.map(item => <li key={item.id}>{item.text}</li>)}
      </ul>
    </div>
  );
};

const App = () => {
  return (
    <div>
      <h2>Сегодня:</h2>
      <ToDoList
        items={[
          { id: 1, text: "Полить цветы" },
          { id: 2, text: "Помыть машину" },
          { id: 3, text: "Выкинуть мусор" },
        ]}
      />
      <h2>Завтра:</h2>
      <ToDoList items={[]} />
    </div>
  );
};

export default App;
		

Решение

Если вы запустите код, вы заметите, что список дел на завтра отображает 0.

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

			true && "hello world" // "hello world" will be rendered
false && "hello world" // nothing will be rendered
		

Это работает, потому что React ничего не отобразит для логического значения false. Однако проблема с компонентом ToDoList заключается в том, что мы проверяем items.length, который возвращает 0, если элементов нет, что React отобразит как допустимый фрагмент JSX.

Как это исправить?

Самое простое решение — всегда использовать тернарный оператор при условном рендеринге в React:

			import React from "react";

const ToDoList = ({ items }) => {
  return (
    <div>
      <ul>
        {items.length
          ? items.map((item) => <li key={item.id}>{item.text}</li>)
          : null}
      </ul>
    </div>
  );
};

const Apps = () => {
  return (
    <div>
      <h2>Today:</h2>
      <ToDoList
        items={[
          { id: 1, text: "Полить цветы" },
          { id: 2, text: "Помыть машину" },
          { id: 3, text: "Вынести мусор" }
        ]}
      />
      <h2>Tomorrow:</h2>
      <ToDoList items={[]} />
    </div>
  );
};

export default App;
		

Таким образом, вы явно указываете React, что отображать, если левая часть тернарной операции ложна — в этом случае, если элементов нет, мы хотим отобразить null. Как и ожидалось, для завтрашнего списка дел ничего не отображается.

Это хороший шаблон, поскольку он заставляет вас более думать о ложных случаях в вашем коде. Например, в этом случае было бы неплохо отобразить некоторый текст, сообщающий пользователю, что список дел пуст.

В будущем следует обратить внимание на то, что может помочь с условным рендерингом, это выражение do, которое позволят нам делать что-то вроде этого:

			return (
  <nav>
    <Home />
    {
      do {
        if (loggedIn) {
          <LogoutButton />
        } else {
          <LoginButton />
        }
      }
    }
  </nav>
)
		

В настоящее время do находится на стадии предложения, но, на мой взгляд, этот способ понятнее и проще в использовании, чем тернарные условия, особенно когда есть несколько вложенных условий.

Спасибо за внимание!

Найдите ошибку: Функциональное Карри

Источник

Следите за новыми постами
Следите за новыми постами по любимым темам
5К открытий5К показов