useAsync Custom hook 사용하기

20829 단어 ReactReact

useAsync

해당 코드는 출처에 담긴 코드를 사용하였고
그 코드를 잘 다루기 위해서 사용하였다.

사용할 컴포넌트

해당컴포넌트를 응용해서 수정해본다.

코드 내용

import Avatar from "@mui/material/Avatar";
import AvatarGroup from "@mui/material/AvatarGroup";
import CircularProgress from "@mui/material/CircularProgress";
import Box from "@mui/material/Box";
import PropTypes from "prop-types";
import { makeStyles } from "@material-ui/core/styles";
import useAsync from "../utils/hooks/useAsync";

const useStyles = makeStyles({
  avatar: ({ width, height }) => ({
    width: `${width}px!important`,
    height: `${height}px!important`,
  }),
});

const wait = (timeToDelay) =>
  new Promise((resolve) => setTimeout(resolve, timeToDelay));

//dummy Data
const dataArr = [
  {
    name: "mmmm",
    image: "/",
    id: "khw970421",
  },
  {
    name: "김",
    image: "/",
    id: "khw97wdlwloed0",
  },
  {
    name: "박",
    image: "",
    id: "kii9222swwsss",
  },
  {
    name: "윤",
    image: "",
    id: "kqwjeowos11ss",
  },
  {
    name: "윤",
    image: "",
    id: "kqwjeowos11ss",
  },
  {
    name: "윤",
    image: "",
    id: "kqwjeowos11ss",
  },
  {
    name: "윤",
    image: "",
    id: "kqwjeowos11ss",
  },
];

// 사이즈 크기 자유롭게

async function getUsers() {
  await wait(1000);
  return dataArr;
}

const Profile = ({ max, width, height }) => {
  const classes = useStyles({ width, height });
  const [state, refetch] = useAsync(getUsers, []);
  const { loading, data: users, error } = state; // state.data 를 users 키워드로 조회

  console.log(max, width, height, refetch);

  //Avatar 태그 클릭시 이벤트
  const clickAvatarHandler = (id) => {
    //해당 대상의 마이페이지로 이동하는 함수 구현
    console.log(id);
  };

  if (loading)
    return (
      <Box sx={{ display: "flex" }}>
        <CircularProgress style={{ color: "#FD9F28", width, height }} />
      </Box>
    );
  if (error) return <div>에러가 발생했습니다</div>;
  if (!users) return null;
  return (
    <>
      <AvatarGroup max={max} classes={{ avatar: classes.avatar }}>
        {users.map(({ name, image, id }) => {
          return (
            <Avatar
              key={id + Math.random()}
              alt={name}
              src={image}
              onClick={() => {
                clickAvatarHandler(id);
              }}
            />
          );
        })}
      </AvatarGroup>{" "}
    </>
  );
};

Profile.defaultProps = {
  max: 3,
  width: 40,
  height: 40,
};

Profile.propTypes = {
  max: PropTypes.number,
  width: PropTypes.number,
  height: PropTypes.number,
};

export default Profile;

추가한 코드

  1. wait메소드 (아직 API가 제대로 되어있지않아 setTimeout을 async await에서 사용하기 위해)
  2. useAsync Hook
  3. if문 형식 (기존에 삼항연산자일때는 users를 미리 알아야하는데 이를 가져오지 못해서 에러가 났다.)
  • 결과 자체는 기존 링크의 코드와 동일하나 해당 Hook을 통해 각각의 컴포넌트마다 따로 Loading을 고려하고 처리하는 중복되는 코드를 막을 수 있다.

setTimeout async await

setTimeout은 Promise반환을 하지 않기 때문에 async와 await를 적용해도 동기적으로 적용되지 않는다

  • 즉, Promise를 반환하게 직접 작성 후 async와 await를 적용해야한다.
const wait = (timeToDelay) => 
             new Promise((resolve) => 
             setTimeout(resolve, timeToDelay)) //이와 같이 선언 후
await wait(5000) 
  • 따라서 코드는 이와 같이 적용시켜야한다.

출처

useAsync
async await

좋은 웹페이지 즐겨찾기