22.10.19~20

커피 내리는 그냥 사람·2022년 10월 20일
0

항해99

목록 보기
37/108

과제를 주요 코드 및 주석/개념 정리

깃허브

1. module

todosSlice와 commentsStlice와 유사하여 commentsSlice 위주로 작성(comments가 조금 더 복잡했음.)

댓글 CRUD

공통 : thunk 미들웨어 이용해서 state값 바로 가져오는 것 아닌 서버와 통신하며 케이스 나눠서 함.

1. Create

export const __addComments = createAsyncThunk(
  "comments/addComments",
  async (payload, thunkAPI) => {
    try {
      const data = await axios.post(params.key, payload);
      // payload를 comments.jsx에서 obj로 받아 바로 더하기
      // 공통 : params.key는 .env에 숨겨놓은 local url(배포때는 바꿈)
      return thunkAPI.fulfillWithValue(data.data);
      // 객체로 변환해서 return 해 줌
    } catch (error) {
      return thunkAPI.rejectWithValue(error);
    }
  }
);

...
...

(extraReducer pt)
    [__addComments.fulfilled]: (state, action) => {
      state.isLoading = false; // 네트워크 요청이 끝났으니, false로 변경합니다.
      state.commentList.push(action.payload); // 교체가 아니라 추가하는거다.

2. Read

export const __getComments = createAsyncThunk(
  "comments/getComments",
  async (payload, thunkAPI) => {
    try {
      const data = await axios.get(params.key);
      const selCommentList = data.data.filter((val) => {
        return Number(payload) === Number(val.commentId);
      });
      return thunkAPI.fulfillWithValue(selCommentList);
    } catch (error) {
      return thunkAPI.rejectWithValue(error);
    }
  }
);

3. Update

export const __editComments = createAsyncThunk(
  "comments/editComments",
  async (payload, thunkAPI) => {
    // id와 수정값 payload로 받아 옴
    try {
      const params = {
        key: process.env.REACT_APP_COMMENT,
      };
      await axios.patch(`${params.key}/${payload.id}`, payload.editComment);
      const data = await axios.get(params.key);
      // 수정한 이후 갑을 한 번 더 받아옴
      const filterData = data.data.filter((val) => {
        return val.id === payload;
      });
      // filter로 id 값이 같은 것만 수정할 수 있게 함
      return thunkAPI.fulfillWithValue(filterData.body);
      // data의 body 값을 return
    } catch (error) {
      return thunkAPI.rejectWithValue(error);
    }
  }
);

4. Delete

export const __deleteComments = createAsyncThunk(
  "comments/deleteComments",
  async (payload, thunkAPI) => {
    // payload로 id 받아온다.
    try {
      const params = {
        key: process.env.REACT_APP_COMMENT,
      };
      const data = await axios.delete(`${params.key}/${payload}`);
      // delete 이용해서 id 값 지워준다.
      return thunkAPI.fulfillWithValue(payload);
      // data.data를 넘겨주는게 아니라 아래서 쓸 id, 즉 payload를 넘겨준다.
    } catch (error) {
      return thunkAPI.rejectWithValue(error);
    }
  }
);


...
...

[__deleteComments.fulfilled]: (state, action) => {
      state.isLoading = false; // 네트워크 요청이 끝났으니, false로 변경합니다.
      state.commentList = state.commentList.filter(
        (item) => item.id !== action.payload
      );
      // 바로 지워지려면 state.commentList를 설정...
      // 서버 단에서 지우는게 있고 리덕스에서 지우는게 따로 있다.

2. component

1. 게시물 id 처리 로직

  const { isLoading, error, todos } = useSelector((state) => state.todos);
  //id최대값
  const getMaxId = () => {
    let stateIdArr = todos.map((element) => {
      // useSelect 한 todos map 돌린 후 거기서 나온 id를 리턴해서 전개연산함
      return Number(element.id);
    });
    return Math.max(...stateIdArr);
  };


....
....

    const obj = {
      id: getMaxId() + 1,
      title: title.title,
      body: body.body,
      writer: writer.writer,
    };
// 오련 식

2. .env 값 설정하여 url 코드상에서 가리기

  const params = {
    key: process.env.REACT_APP_COMMENT,
  };

.env를 루트 디렉토리에 만든 뒤

REACTAPP변수명= "url"

로 설정해준다.

아쉬운 점 : .gitIgnore에 숨겨야 하는데 숨기면 창이 안 떠서 못 숨겼다... 어떻게 방법이 없었을까...

3. dispatch를 각 함수 안에서 활용

comment delete 예시

const onClickDelButtonHandler = (id) => {
    dispatch(__deleteComments(id))
    };

그 외에도 다양한 방식으로 dispatch를 다른 훅과 매개변수와 조합해서 씀.(useEffect 등)

4. window.confirm

onClick={() => {
                const result = window.confirm("이 댓글을 지울까요?");
                if (result) {
                  return onClickDelButtonHandler(item.id);
                } else {
                  return;
                }
              }}

취소 / 확인 alert를 만들어주는 메서드인듯. 유용하게 썼다. 쓰는 법 잘 익혀놓으면 좋을 것 같다. 꼭 window를 먼저 써주길.

3. pages

1. prev 활용 by 기술매니저님

(TodoDetail.jsx)

// ⭐️prev는 setDetail의 이전 값을 가져오는 것
    // 업데이트 시키기 전에 처음에 있던 state 값을 prev로 가져올 수 있음.
    // prev의 무슨 값을 넣든 이전 값을 가져옴

    setDetail((prev) => ({
      ...prev,
      body: editTodo.body,
    }));

2. stopPropagation()

(TodoList.jsx)

onClick={(event) => {
                event.stopPropagation();
                // 이벤트 버블링을 막는 법. 삭제, 여백 등 같이 있을 때 이벤트가 퍼질 때 막는 것

4. customHook

(useInput.js)

import React, { useState } from "react";

const useInput = () => {
  // 2. value는 useState로 관리,
  const [tempName, setName] = useState({
    writer: "",
    title: "",
    body: "",
  });

  // 3. 핸들러 로직도 구현.
  const handler = (e) => {
    const { name, value } = e.target;
    setName({
      ...tempName,
      [name]: value,
    });
  };

  // 1. 이 훅은 [ ] 을 반환하는데, 첫번째는 value, 두번째는 핸들러를 반환.
  return [tempName, handler];
};

export default useInput;

input을 실제로 Form.jsx 에서 사용한 케이스

const Form = () => {
  //커스텀 훅
  const [title, onChangeTitleHandler] = useInput();
  const [body, onChangeBodyHandler] = useInput();
  const [writer, onChangeWriterHandler] = useInput();
// 이 다음부터는 값 받을 때 title, body, writer에서 받고 onChnageHandler도 on~ 에서 따로 받는다.
  

5. Button.js 로 버튼 일원화 관리

import React from "react";
import styled, { css } from "styled-components";

const Button = (props) => {
  return (
    <StButton {...props} disabled={props.disabled}>
      {props.children}
      {/* 부모에서 자식꺼를 쓸 수 있는 것 
      부모 : 
      <>
      <자식/>
      </>
      */}
    </StButton>
  );
};

export default Button;

const StButton = styled.button`
  border: 1px solid gray;
  background-color: #fff;
  height: 46px;
  border-radius: 8px;
  background-color: ${({ bgColor, disabled }) => (disabled ? "#ddd" : bgColor)};
  cursor: pointer;

  ${({ size }) => {
    switch (size) {
      case "large":
        return css`
          width: 100%;
        `;
      case "medium":
        return css`
          width: 80px;
        `;
      case "small":
        return css`
          width: 30px;
          height: 30px !important;
        `;
      default:
        return css`
          width: 120px;
        `;
    }
  }}
`;

이후 모든 버튼이 들어간 곳에 Button 을 상속시켜주면 사용이 가능하다.

6. .env 개발환경과 배포로 나누기

  • 원래 리엑트가 자동으로 읽어줘서 개발부터 읽고 배포되면 배포를 읽는게 맞다.
    = 안 될 경우 env-cmd를 설치해서 해결한다.
    참고 블로그
profile
커피 내리고 향 맡는거 좋아해요. 이것 저것 공부합니다.

0개의 댓글