首页 > 解决方案 > 反应钩子和 fetch() 建议

问题描述

我有一个组件可以获取一个随机人,将其保存到一个状态变量数组中,并在通过该数组进行映射后,它返回某些元素。我的目标是使用头像和个人信息呈现“社交卡”,我想为此使用材质 UI CARD 组件。另外,我想在这里获得有关我的逻辑的任何反馈,这是否是实现我所取得的成就的好方法。setTimeout() 只是在那里,所以我可以渲染一些加载动画。此外,当我尝试在数组映射中返回完整的卡片组件时,我无法渲染 {item.something.something}

export default function SocialCardsfunction() {
  const [items, setItems] = useState([]);
  const [loading, setLoading] = useState(true);

  const classes = useStyles();

  const nextPerson = () => {
    fetch("https://randomuser.me/api")
      .then((response) => response.json())
      .then((response) => {
        setItems(response.results);
      });
  };
  
  useEffect(() => {
    fetch("https://randomuser.me/api")
      .then((response) => response.json())
      .then((response) => {
        setTimeout(() => {
          setItems(response.results);
          setLoading(false);
        }, 1000);
      });
  }, []);

  if (loading) {
    return <div>Loading ...</div>;
  } else {
    return (
      <div>
        {items.map((item, i) => {
          return (
            <div>
              <h2>{item.name.first}</h2>
              <img src={item.picture.large} alt='picture' key={i} />
              <button onClick={() => nextPerson()}>click me</button>
            </div>
          );
        })}
      </div>
    );
  }
}

const useStyles = makeStyles({
  root: {
    minWidth: 275,
  },
  bullet: {
    display: "inline-block",
    margin: "0 2px",
    transform: "scale(0.8)",
  },
  title: {
    fontSize: 14,
  },
  pos: {
    marginBottom: 12,
  },
});

标签: reactjsreact-hooks

解决方案


所做的更改

  1. 不要重复相同的代码,而是创建一个函数并在useEffect.
  2. 列表中的每个孩子都应该有一个唯一的 " key" 道具。
  3. 使用 Material UI 中的卡片。(我没有过多关注样式 XD)
import {
  Button,
  Card,
  CardActions,
  makeStyles,
} from "@material-ui/core";
import React, { useEffect, useState } from "react";

export default function SocialCardsfunction() {
  const [items, setItems] = useState([]);
  const [loading, setLoading] = useState(true);

  const classes = useStyles();

  const fetchPerson = () => {
    fetch("https://randomuser.me/api")
      .then((response) => response.json())
      .then((response) => {
        setTimeout(() => {
          setItems(response.results);
          setLoading(false);
        }, 1000);
      });
  };

  useEffect(() => {
    fetchPerson();
  }, []);

  if (loading) {
    return <div>Loading ...</div>;
  } else {
    return (
      <div>
        {items.map((item, i) => {
          return (
            <div key={i}>
              <Card className={classes.root}>
              <h2>{item.name.first}</h2>
                <img
                  alt="img"
                  src={item.picture.large}
                  className={classes.large}
                />
                <CardActions>
                  <Button onClick={() => fetchPerson()} size="small">Next</Button>
                </CardActions>
              </Card>
           
            </div>
          );
        })}
      </div>
    );
  }
}

const useStyles = makeStyles({
  root: {
    minWidth: 275
  },
  bullet: {
    display: "inline-block",
    margin: "0 2px",
    transform: "scale(0.8)"
  },
  title: {
    fontSize: 14
  },
  pos: {
    marginBottom: 12
  }
});

推荐阅读