我想在我的页面上显示一个元素列表,并且我希望每个元素都具有“显示更多/更少”功能来随意扩展和缩短文本。

为此,我将使用 React。我将从以下虚拟 API 获取一些假数据 u003d>jsonplaceholder.typicode.com

我将使用axios这样做。

我的结构中将包含三个页面:App.js、Texts.js 和 Text.js。

你可以在这里找到 repo u003d>github.com/muratcan-yuksel/reactShowHideBlo..

我将在 App.js 中获取数据,然后将其与 props 一起发送,直到它到达 Text.js 组件。

首先,这是我的 App.js 文件 u003d>

应用组件

//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 端点。您可以通过此链接检查它 u003d>jsonplaceholder.typicode.com/posts它返回用户 ID、ID、标题和正文。我需要body作为文本。

useState hook 用于保存 state 中的数据,useEffect hook 在组件挂载时调用一次 getData 函数。

getData是使用axios库调用API的异步函数,setData(res.slice(0, 5));这行代码为了方便使用,我将API返回的数组元素数量限制为5个,并设置状态。它返回很多项目,我不需要所有项目。在进行 API 调用时,我总是使用 try/catch 语法和 async/await。这是我所知道的最好的,而且我发现语法更具可读性。

在我的 return 语句中,我将保存到 state 的数据发送到带有 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关键字放入花括号中来解构 props。忽略样式提示,您可以查看 github repo 中的 css 文件。

我映射从父级获得的数据,并为每个映射元素创建一个Text组件。跳过此步骤并尝试在此组件中映射和显示数据会导致显示/隐藏逻辑同时应用所有元素,即当单击一个显示/隐藏按钮时,所有其他按钮将显示/隐藏在同时。我们不希望那样。我们希望每个元素都单独显示/隐藏。

我以以下方式发送道具{...mappedProps}以获取子组件中的各个键标题,以便我可以像这样导入从 API 返回的内容 u003d>

//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 中给出的键名的道具,例如 u003d>const Text = ({ body, id }) => {,在我看来,这样可以减少混淆的空间。我知道我要找的是body。我给每个单独的 div id,然后用这条线

   {readMore ? body : `${body.substring(0, 80)}...`}

我告诉浏览器首先检查readMore状态变量是否为真,如果是,则显示来自body的整个测试;如果为 false,则仅显示文本的前 80 个字符。由于readMore状态变量一开始就设置为false,所以当我打开页面时,我会看到缩短的文本。我在缩短的文本后面有三个点。然后我放了一个带有以下片段的按钮u003d>

    <button className="btn" onClick={() => setReadMore(!readMore)}>
     {readMore ? "show less" : "  read more"}
    </button>

它将readMore状态变量设置为相反的值。如果readMore状态变量是true,则按钮内部有一个文本显示“显示更少”,如果它是false,则显示“阅读更多”。有了这个,我就可以点击按钮来扩大和缩小文本。

而已。

快乐编码!

Logo

React社区为您提供最前沿的新闻资讯和知识内容

更多推荐