[TIL] 230707

이세령·2023년 7월 7일
0

TIL

목록 보기
51/118

Read 구현

카드 리스트를 불러오기 위해 Read 먼저 구현해주었다.
api/studyTodo.js

import axios from "axios";

// 조회
const getStudyList = async () => {
  const response = await axios.get(`${process.env.REACT_APP_SERVER_URL}/study`);
  console.log("res", response);
  return response.data;
};

export { getStudyList };

CardList에서 Card로 넘겨주고, react-query로 오류 처리를 해줬다.
카드의 완료 상태에 따라 색이 다르도록 설정해줬다.

components/CardList.jsx

function CardList() {
  const { isLoading, isError, data } = useQuery("study", getStudyList);

  if (isLoading) {
    return <h1>로딩중</h1>;
  }
  if (isError) {
    return <h1>오류가 발생하였습니다....!!!</h1>;
  }

  return (
    <div>
      <CardListBox>
        {data.map((item) => {
          return <Card key={item.id} study={item} />;
        })}
      </CardListBox>
    </div>
  );
}

components/Card.jsx

function Card({ study }) {
  return (
    <CardBox done={study.isDone}>
      <CardNav>
        <div>작성자 {study.writer}</div>
        <MdDeleteForever IoIosClose size="25"></MdDeleteForever>
      </CardNav>
      <Cardcontext>{study.title}</Cardcontext>
      <Cardfooter>
        <div>
          <Button color="#ffffff">{study.isDone ? "완료" : "미완료"}</Button>
        </div>
      </Cardfooter>
    </CardBox>
  );
}

export default Card;

const CardBox = styled.div`
  background-color: ${(props) => (props.done ? "#9dc3c1" : "#6E7783")};
  width: 18rem;
  border-radius: 4px;
  margin: 1rem;
  flex-direction: column;
  &:hover {
    cursor: pointer;
  }
`;

Input custom hook

post에서 input을 사용하는데 중복 코드를 줄이기 위해 custom hook을 만들었다.

useInput.js

import { useState } from "react";

const useInput = () => {
  // state
  const [value, setValue] = useState("");

  // handler
  const handler = (e) => {
    setValue(e.target.value);
  };
  return [value, handler];
};

export default useInput;

post.jsx

  const [title, onChangeTitleHandler] = useInput();
  const [writer, onChangeWriterHandler] = useInput();
  const [content, onChangeContentHandler] = useInput();
.
.
<div>
            <label>제목</label>
            <input value={title} onChange={onChangeTitleHandler} />
          </div>
          <div>
            <label>작성자</label>
            <input value={writer} onChange={onChangeWriterHandler} />
          </div>
          <div>
            <label>내용</label>
            <textarea value={content} onChange={onChangeContentHandler} />
          </div>

Post

Post로 이동하는 + 버튼 위치

const PostButton = styled.div`
  position: fixed;
  bottom: 40px;
  right: 30px;
`;

다음과 같이 위치를 고정하면 스크롤을 내려도 항상 같은 위치에 나타난다.

post 저장

react query를 이용해서 input을 customhook을 이용하고 해당 값이 저장되도록 코딩하였다.

const queryClient = useQueryClient();
  const mutation = useMutation(addStudyList, {
    onSuccess: () => {
      queryClient.invalidateQueries("study");
      console.log("Post 성공");
    },
  });

  const handleSubmitButtonClick = (event) => {
    event.preventDefault();
    // 유효성 검사
    // 1. 제목, 내용 모두 입력되어야 한다.
    if (!title || !writer) {
      return alert("제목 또는 내용이 입력되지 않았습니다!");
    }

    const newStudyTodo = {
      title,
      contents,
      writer,
      isDone: false,
    };

    mutation.mutate(newStudyTodo);

    setTitle("");
    setWriter("");
    setContent("");
    alert("저장되었습니다!");
    navigate("/");
  };

제목이나 내용이 빈값이면 저장되지 않고 경고창을 나타나게 만들었고, mutate를 통해 addStudyList를 동작하여 study 쿼리에 newStudyTodo가 post되고 기존 쿼리를 queryClient.invalidateQueries("study");로 무효화 하여 렌더링되게 만들어준다.

Detail Page

url을 id를 통해 자세히 불러올 수 있어서 api/studyTodo.js에 상세 페이지를 조회하는 코드를 작성했다.

// 상세 페이지 조회
const getStudy = async (id) => {
  const response = await axios.get(
    `${process.env.REACT_APP_SERVER_URL}/study/${id}`
  );
  console.log("detail res", response);
  return response.data;
};

불러올 때 해당 코드를 작성했는데

const { isLoading, isError, data } = useQuery(`${param.id}`, 
    getStudy(param.id)
  );

계속 실행을 해서 어디가 문제인가 했는데, 화살표함수를 사용하지 않아서 계속 무한 렌더링이 발생하였다.

const { isLoading, isError, data } = useQuery(`${param.id}`, () =>
  getStudy(param.id)
);

이렇게 고쳐주면 값이 한번만 잘 받아진다!

새로 알게된 정보들

  • stop propagation 알아보기 -> 바깥으로 안퍼진다. 이벤트 버블링 방지
  • 렌더링 줄이는 법
    state 최소한으로 컴포넌트 안에 가둔다(?)
  • react developer tools
    렌더링 되는 것을 볼 수 있다. 구글 확장

서버와 통신을 하면서 값이 바뀌어 렌더링이 되는데, 어떻게 줄일 수 있는 방법이 있을지 고민하다가 튜터님은 통신을 하는 부분에서 발생하는 것은 어쩔 수 없이 가져간다고 하신다.
이번에 query를 직접 적용해보면서 진행하였는데, query와 redux가 어떤점이 다를까 고민해보았다. query는 통신이 있을 때 사용하고 redux는 통신이 필요없는 상태를 관리할 때 사용하는 것 같다.

profile
https://github.com/Hediar?tab=repositories

0개의 댓글