TIL 12 03.29

공부한 내용

1. 알림창 꾸미기 ⇒ Modal

2. 주소, 우편번호 검색 ⇒ React-Daum-Postcode

3. setState 기능 추가로 배우기 ⇒prevState

4. 리팩토링(refactoring)

5. JS공부


복습하기

아이콘 자체를 새로운 스타일 컴포넌트로 선언해주고 속성 지정해줄 수 있었다.

그러고 그 아이콘이 들어간 버튼을 클릭했을 때 함수를 생성하고 버튼을 누를때 마다 다시 화면을 보여주기 위해 refetchQueries를 달아줬다.
백엔드에서 like와 dislike를 백엔드에서 받아오는 것도 잊지말고 해야함

  • 댓글에 별점 넣기

나중을 위해서라도 속성이 없더라도 새롭게 선언해줘

// 댓글 작성 컨테이너
const [star, setStar] = useState(0);
// 스타는 0부터 시작

function onChangeStar(value: number) {
    setStar(value);
  }
// 온체인지의 기능은 value를 star에 넣어줘

~~~
await createBoardComment({
        variables: {
          createBoardCommentInput: {
            writer,
            password,
            contents,
            rating: star,
          },
~~~ // rating에 star의 벨류를 넣어주고 
//*백엔드에서 rating가져오기 까먹지마

// 댓글 작성 JSX
<S.Star onChange={props.onChangeStar} />
// 온체인지로 onChange 기능 넣어주고

//댓글 목록 JSX
<S.Star value={el?.rating} disabled />
// 레이팅을 다시 부분에 넣어주고 disabled로 선택 못하게
  • 유튜브 링크 넣기

유튜브를 넣은 input을 만들어주고

const [youtubeUrl, setYoutubeUrl] = useState("");

const onChangeYoutubeUrl = (event: ChangeEvent<HTMLInputElement>) => {
    setYoutubeUrl(event.target.value);
  };

뮤테이션에서 youtubeUrl를 보내주고

fetchBoard에서도 youtubeUrl를 추가적으로 받아줘야겠지?

조건부 랜더링으로 유튜브 url를 선택적으로 보여주기로 상세페이지에 작성함

*react-player에서는 크기만 여기서 지정
스타일 컴포넌트에서는 위치만 지정하기 위해서 margin만 줬어

수정하기 페이지에선 디폴트 벨류로 Url를 보여줘
*여기서 defaultValue에는 string을 보여줘야 하는데 그냥 true 값만 넣어주면 false값은 undefined가 되기때문에 타입오류 발생 || “”으로 있거나 없거나 둘 다 string을 보여줘서 타입 오류를 해결!

수정 페이지에서도 youtubeUrl를 받아줘야 props.data에 youtubeUrl이 쭉 이어지게 됨

수정할 때도 유튜브 주소가 있었으면 추가해줘야하니까 넣어주고

만약에 Url이 있었고 변경 됐으면 다시 인풋밸류에 넣어줘

이때 타입 오류가 뜰 수 있는데 그때는 타입파일에 youtubeUrl에 대한 속성을 넣어줘야함


알림창 꾸미기

Modal-Ant Design 활용

  1. alert 창 modal로 구현하기
  2. prompt 창 modal로 구현하기

게시물 등록이나 회원가입도 모달로 만들 수 있다!

  • 기본적인 모달 활용

const onClickSuccessButton = () => {
    Modal.success({ content: "게시물 등록에 성공했습니다." });
  };

<button onClick={onClickSuccessButton}>성공했을때!</button>

import { Modal } from "antd";

const ModalAlertPage = () => {
  const onClickSuccessButton = () => {
    Modal.success({ content: "게시물 등록에 성공했습니다." });
  };
  const onClickFailButton = () => {
    Modal.error({ content: "비밀번호가 틀렸습니다." });
  };

  return (
    <div>
      <button onClick={onClickSuccessButton}>성공했을때!</button>
      <button onClick={onClickFailButton}>실패했을때!</button>
    </div>
  );
};
export default ModalAlertPage;

alert(”게시물 등록에 성공했습니다.”) 대신 Modal.success , Modal.error를 사용한 내용

  • 모달을 커스텀하는 방법
const [isModalVisible, setIsModalVisible] = useState(false);
// 기본값 false

  const showModal = () => {
    setIsModalVisible(true);
  }; // 클릭하면 true로

  const handleOk = () => {
    setIsModalVisible(false);
  }; // ok를 클릭하면 false로

  const handleCancel = () => {
    setIsModalVisible(false);
  }; // cancel을 클릭하면 false로

여기서 isModalVisible은 그냥 useState로 선언해준 새로운 값일 뿐이기 때문에

아래 처럼 isOpen으로 간단하게 줄이고 비밀번호를 요구하는 input을 넣어 비밀번호 입력창으로 바꿔봤다.

조건부 렌더링과 true, false를 밑에서 나올 prev를 사용해서 줄임으로써 리팩토링 할 수도 있다.

import { useState } from "react";
import { Modal, Button } from "antd";

const ModalCustomPage = () => {
  const [isOpen, setIsOpen] = useState(false);
  const [password, setPassword] = useState("");

  const showModal = () => {
    setIsOpen(true);
  };

  const handleOk = () => {
    setIsOpen(false);
  };

  const handleCancel = () => {
    setIsOpen(false);
  };

  const onChangePassword = (event) => {
    setPassword(event.target.value);
  };

  return (
    <>
      <Button type="primary" onClick={showModal}>
        Open Modal
      </Button>
      <Modal
        title="비밀번호를 입력하세요"
        visible={isOpen}
        onOk={handleOk}
        onCancel={handleCancel}
      >
        비밀번호 입력: <input type="password" onChange={onChangePassword} />
      </Modal>
    </>
  );
};
export default ModalCustomPage;

주소, 우편번호 검색

react-daum-postcode 다운로드

npm install --save react-daum-postcode

yarn add react-daum-postcode

Modal에 그냥 인풋을 넣는게 아니라 react-daum-postcode를 활용해서 주소, 우편번호 검색 모랄로 커스텀

import { useState } from "react";
import DaumPostcode from "react-daum-postcode";
// 주소, 우편번호 검색 컴포넌트를 불러온다.
import { Modal, Button } from "antd";
// antd를 통해 모랄, 버튼 컴포넌트를 불러온다.

const ModalCustomPage = () => {
  const [isOpen, setIsOpen] = useState(false);

  const showModal = () => {
    setIsOpen(true);
  };

  const handleOk = () => {
    setIsOpen(false);
  };

  const handleCancel = () => {
    setIsOpen(false);
  };

  const handleComplete = (data: any) => {
    console.log(data);
    setIsOpen(false);
  };

  return (
    <>
      <Button type="primary" onClick={showModal}>
				// primary는 색 등의 css속성을 넣어 놓은 것
        Open Modal
      </Button>
      {isOpen && (
        <Modal
          title="주소 입력창"
          visible={true}
          onOk={handleOk}
          onCancel={handleCancel}
        >
          <DaumPostcode onComplete={handleComplete} />
        </Modal>
      )}
    </>
  );
};
export default ModalCustomPage;
  • 모달을 숨겼다가 나타나게 하는 방법 / 삭제하고 새로 만드는 방법 두 가지 가능

감췄다가 다시 여는 방식 visible={isOpen}로 컨트롤

{/*  visible로 모달 숨겼다가 나타나게 하는 방법 */}
      <Modal
        title="주소 입력창"
        visible={isOpen}      
        onOk={handleOk}
        onCancel={handleCancel}
      >
        <DaumPostcode onComplete={handleComplete} />
      </Modal> 

조건부 랜더링으로 삭제하고 새로 만드는 방법

{/* 모달 삭제하고 새로 만드는 방법 */}
      {isOpen && (
        <Modal
          title="주소 입력창"
          visible={true}
          onOk={handleOk}
          onCancel={handleCancel}
        >
          <DaumPostcode onComplete={handleComplete} />
        </Modal>
      )}

prevState

주석의 내용처럼 4번 연속해서 사용해도 결과가 1이 나오는 이유는 위에서 useState를 통해 초기값을 0으로 지정해줬기 때문에!

위에 내용을 prev를 사용하여 바꾸면 원하는 결과를 얻을 수 있다.

위에 useState로 초기값을 0을 줬으니까 임시저장공간에 0이 저장되어 있고 임시저장공간에서 처음 0을 prev가 가져오고 그 prev+1을 다음 prev가 가져오는 방식!


리팩토링 refactoring

먼저 리팩토링을 한 결과는 아래와 같다

리팩토링을 하는 과정을 풀어보겠다.

위에서 사용했던 prev를 활용해서 주소 모랄 컴포넌트를 바꾸보면 아래처럼 바꿀 수 있는데

풀어서 설명하면 기존에 useState에 초기값으로 false를 setIsOpen(prev)으로 가져오고 (prev) ⇒ !prev를 통해서 prev값에 있던 false를 true로 표현하는 방식으로 아래처럼 만들어줬다.

그럼 같은 setIsOpen((prev) ⇒ !prev)를 사용하는 여러개의 함수가 선언된거기 때문에 함수를 합쳐보면

const onToggleModal = () => {
    setIsOpen((prev) => !prev);
  };

이렇게 같은 기능을 실행하는 함수 1개로 합친 후에 선언된 함수를 기존에 나눠졌던 함수들 자리에 다시 넣어서 완성을 해보면

// import 생략

const ModalCustomPage = () => {
  const [isOpen, setIsOpen] = useState(false);

  const onToggleModal = () => {
    setIsOpen((prev) => !prev);
  };

  const handleComplete = (data: any) => {
    console.log(data);
    onToggleModal();
  };

  return (
    <>
      <Button onClick={onToggleModal}>Open Modal</Button>
      {isOpen && (
        <Modal visible={true} onOk={onToggleModal} onCancel={onToggleModal}>
          <DaumPostcode onComplete={handleComplete} />
        </Modal>
      )}
    </>
  );
};
export default ModalCustomPage;

이렇게 완성할 수 있다!

최종적으로 리팩토링 된 점

visible로 컨텐츠를 보여주는 것을 항상 true로 지정하고 modal 전체를 조건부 랜더링으로 클릭을 할 때 새롭게 보여주고 닫으면 삭제 하는 방식을 사용해줬고 button의 타입으로 primary가 지정되어 있었는데 이는 기능과 상관없는 css요소기 때문에 필요하지 않아서 제거, prev 를 활용해서 여러 개의 함수를 하나의 함수로 지정했다.


JS공부 - 객체의 구조 분해 할당(비구조화 할당)

Destructuring Assignment

const aboutMe = {
name : "가나다",
age : 26,
position : "학생",
adress : "영등포구"
}

위와 같은 객체에서 position만 가져올 때

const 변수 = 기존객체(aboutMe).position으로 다른 변수에 담아서 사용

여러가지 내용들을 한 번에 가져올 때 매번 다른 변수에 담지 않고 조금 더 편하게 사용하게 해주는것을 비구조화 할당, 구조분해 할당이라고 합니다.

한 배열이나 객체에 담겨있던것을 하나씩 분해하는것비구조화 할당이라고 함

배열 분해

const numbers = [0, 1, 2];

let [zero, one, two] = numbers; // 선언과 동시에 할당

// 위의 결과물이 아래와 같다.
let zero = 0
let one = 1
let two = 2

let으로 새로운 배열을 선언을 하면서 numbers라는 배열에 인자들을 담아서 할당을 해줄 수 있다.

useMutation, useState는 배열을 할당하고 useQurey는 객체를 할당함

좋은 웹페이지 즐겨찾기