Код элементов списка с функцией «показать больше/меньше» в React

Я хочу отобразить список элементов на моей странице, и я хочу, чтобы каждый элемент имел функцию «показать больше/меньше» для расширения и сокращения текста по желанию.

Для этого я буду использовать React. Я получу некоторые фиктивные данные из следующего фиктивного API => https://jsonplaceholder.typicode.com/.

Для этого я буду использовать axios.

В моей структуре будет три страницы: App.js, Texts.js и Text.js.

Вы можете найти репозиторий здесь => https://github.com/muratcan-yuksel/reactShowHideBlogPost.

Я буду получать данные в App.js, затем отправлять их с реквизитами, пока они не достигнут компонента Text.js.

Чтобы начать, вот мой файл App.js =>

Компонент App

//App.js
import { React, useState, useEffect } from "react";
import axios from "axios";
import Texts from "./Texts";

const App = () => {
  const url = "https://jsonplaceholder.typicode.com/posts";
  const [data, setData] = useState([]);

  const getData = async () => {
    try {
      const req = await axios.get(url);
      const res = await req.data;
      setData(res.slice(0, 5));
    } catch (error) {
      console.log(error);
    }
  };

  //useEffect runs once when the component is mounted
  useEffect(() => {
    getData();
  }, []);

  return (
    <main>
      <Texts props={data} />
      {/* <div>
        {data.map((e) => {
          return <div key={e.id}>{e.title}</div>;
        })}
      </div> */}
    </main>
  );
};

export default App;
Вход в полноэкранный режим Выйти из полноэкранного режима

Я начинаю с импорта хуков, которые я буду использовать, axios и дочернего компонента Texts.

Я определяю конечную точку API, к которой я буду обращаться. Вы можете проверить его по этой ссылке => https://jsonplaceholder.typicode.com/posts он возвращает идентификатор пользователя, id, заголовок и тело. Мне понадобится body для текста.

Хук useState используется для сохранения данных в состоянии, а хук useEffect вызывает функцию getData один раз при монтировании компонента.

getData — это асинхронная функция, которая вызывает API, используя библиотеку axios, с этой строкой кода setData(res.slice(0, 5)); Я ограничиваю количество элементов массива, возвращаемых API, до 5 для удобства использования и устанавливаю состояние в соответствии с этим. Он возвращает много элементов, мне не нужны все из них. Я всегда использую синтаксис try/catch с async/await при выполнении вызовов API. Это лучший вариант, который я знаю, и я нахожу синтаксис более читабельным.

В своем операторе return я отправляю данные, которые я сохранил в состояние, компоненту Texts с именем props props.

Давайте проверим компонент Texts.

Компонент Texts

//Texts.js
import { React, useState } from "react";
import "./styles/texts.css";
import Text from "./Text";

const Texts = ({ props }) => {
  return (
    <div className="textComponent">
      <div>
        {props.map((mappedProps) => {
          return <Text key={mappedProps.id} {...mappedProps} />;
        })}
      </div>
    </div>
  );
};

export default Texts;
Вход в полноэкранный режим Выход из полноэкранного режима

После импорта соответствующих зависимостей я начинаю с деструктуризации реквизитов, помещая ключевое слово props в фигурные скобки. Не обращайте внимания на подсказки по стилю, вы можете проверить css-файл в репозитории github.

Я сопоставляю данные, полученные от родителя, и создаю компонент Text с каждым сопоставленным элементом. Пропуск этого шага и попытка отобразить данные в этом компоненте приводит к тому, что логика показа/скрытия применяется ко всем элементам одновременно, т.е. при нажатии на одну кнопку показа/скрытия все остальные будут показаны/скрыты одновременно. Мы этого не хотим. Мы хотим, чтобы каждый элемент показывался/скрывался отдельно.

Я отправляю реквизиты следующим образом {...mappedProps}, чтобы получить отдельные названия клавиш в дочернем компоненте, чтобы я мог просто импортировать то, что возвращается из API, например, так =>

//Text.js
const Text = ({ body, id }) => {
    ...)}
Войти в полноэкранный режим Выйти из полноэкранного режима

Текстовый компонент

//Text.js
import { React, useState } from "react";
import "./styles/texts.css";

const Text = ({ body, id }) => {
  const [readMore, setReadMore] = useState(false);

  return (
    <div>
      <div className="text" key={id}>
        {readMore ? body : `${body.substring(0, 80)}...`}
        <button className="btn" onClick={() => setReadMore(!readMore)}>
          {readMore ? "show less" : "  read more"}
        </button>
      </div>
    </div>
  );
};

export default Text;
Вход в полноэкранный режим Выход из полноэкранного режима

Я начинаю с импорта реквизитов с их ключевыми именами, указанными в API, следующим образом => const Text = ({ body, id }) => {, этот способ оставляет меньше места для путаницы, на мой взгляд. Я знаю, что мне нужен именно body. Я присваиваю id каждому отдельному div, а затем строкой

   {readMore ? body : `${body.substring(0, 80)}...`}
Войти в полноэкранный режим Выйти из полноэкранного режима

Я говорю браузеру сначала проверить, является ли переменная состояния readMore истинной, если да, то отобразить весь тест, исходящий из body; если нет, то показать только первые 80 символов текста. Поскольку в начале переменная состояния readMore установлена в false, когда я открою страницу, я увижу сокращенный текст. Я поставил три точки после сокращенного текста. Затем я поместил кнопку со следующим фрагментом =>

    <button className="btn" onClick={() => setReadMore(!readMore)}>
     {readMore ? "show less" : "  read more"}
    </button>
Войти в полноэкранный режим Выйти из полноэкранного режима

которая устанавливает переменную состояния readMore в противоположное состояние. Внутри кнопки есть текст, который показывает «показать меньше», если переменная состояния readMore true, и «читать больше», если она false. С помощью этого я смогу нажимать на кнопку, чтобы расширять и сжимать текст.

Вот и все.

Счастливого кодинга!

Оцените статью
devanswers.ru
Добавить комментарий