220418

solsolsol·2022년 4월 18일
0

TIL

목록 보기
25/32

구조분해할당(비구조화할당)

객체에서 구조분해할당

const child = {
  name = "Alex",
  age = 13
  school = "abc school"
  
}

const name = child.name
const age = child.age
const school = child.school

// 로 쓰는 대신 아래처럼 구조분해할당을 이용해 한 줄로 정리할 수 있다.

const { name, age, school } = chilid
// child 안에 있는 변수를 빼서 새로운 변수를 만들겠다는 선언
const { data, loading } = useQuert(FETCH_BOARDS)

// 위의 코드 아래처럼 다시 적어줄 수도 있다.
const aaa = useQuery(FETCH_BOARD
aaa.data
aaa.loading

함수를 실행하고 나서 받은 리턴값이 객체

객체의 구조분해할당에서 순서는 중요하지 않고 키값이 중요하다. 객체 안에 선언된 key 를 가져오는 것이기 때문에 틀리지 않도록 주의할 것.

배열에서 구조분해할당

const classmate = ["Alex", "Peter", "Amy]

const child1 = classmate[0]
const child2 = classmate[1]
const child3 = classmate[2]

const [child1, child2, child3] = classmate

useState는 실행 후 리턴 값이 배열


comst [state, setState] = useState("")
const bbb = useState
bbb[0] = state
bbb[1] = setState
// bbb[1](20) 을 넣으면 setState(20)이 된다.

const [ , child2, child3 ] = classmates

// 쓰지 않는 변수가 있다면 , 로 자리를 남겨줘야 한다.

배열은 순서가 중요하다. 사용하지 않는 변수에 , 를 넣어 다음 변수로 넘겨주는 것 잊지 말기.

구조분해할당을 쓰면 좋은 이유

// 1. 구조분해 할당으로 함수 파라미터 받기
function onClickAAA({ name, age, school }){ // 2. 구조분해 할당해서 변수로 받는다
  console.log(name) // "철수"
}

const child = {
  name: "철수",
  age: 13,
  school: "다람쥐초등학교"
}
onClickAAA(child) // 1. 객체 child 를 인자로 넘기면

// 같은 이름을 가진 데이터를 뽑아오기 때문에 순서가 다르거나 인자로 넘어온 데이터 개수가 달라도 옛날 방식과 같은 오류가 나지 않는다.

// 2. 안좋은 옛날 방식
function onClickAAA(name, age, school){ // 2. age에 다람쥐초등학교가 들어가게 된다
  console.log(name)
}

const name: "철수"
const age: 13
const school: "다람쥐초등학교"
onClickAAA(name, school) // 1. 인자로 name과 school을 넘겨주면

Rest parameter

const child = {
  name: "철수",
  age: 8,
  school: "다람쥐 초등학교",
  money: 2000,
  hobby: "수영"
}

money 와 hobby 를 삭제하고 싶다면 delet child.money delete child.hobby 로 지워줄 수 있다. 하지만 다른 곳에서 쓰이고 있을 수 있기 때문에 js에서 원본을 건드리는 행위는 좋지 않다. 이때 구조분해할당과 rest parameter 를 사용해서 값을 지워줄 수 있다.

const { money, hobby, ...rest } = child

rest 에는 { name: "철수", age: 8, school: "다람쥐 초등학교" } 이 들어가게 된다.

위와 같이 rest parameter 를 사용하면 원본에 손상이 가지 않고 데이터를 삭제할 수 있다. ...rest 는 원하는 이름으로 바꿔줄 수 있다.
school 오타났다...

Custom Hooks

useState, useEffect, useQuery, useRouter, useMutation 등과 같이 use 가 붙은 함수들을 react hook 이라고 한다. hook 을 사용하는 함수가 있다면 일반 함수와는 조금 다르게 네이밍을 해준다.
함수명 앞에 use 를 붙여주게 되는데, 이렇게 만들어진 함수를 custom hooks 이라고 부른다. use를 붙이지 않아도 실행은 되지만 Docs에서 권장하고 있는 사항이므로 use를 붙여주도록 하자!


export function useAuth() {
  const router = useRouter();
 
  useEffect(() => {
    if (!localStorage.getItem("accessToken")) {
      alert("로그인 후 이용 가능합니다");
      router.push("/login");
    }
  }, []);
}
function CustomHooksUseAuthPage() {
  // useAuth 를 import 해와서 사용
  useAuth();

  return <div>철수의 프로필 페이지 입니다!!</div>;
}

export default CustomHooksUseAuthPage;

HOC 를 사용했을 때보다 쉽고 간단하게 권한분기 로직이 사용가능해졌다.
여러 곳에서 많이 사용되는 함수가 있다면 hooks 폴더를 만들어 빼서 관리해주자. 컴포넌트가 깔끔해진다.

Cache Modify

컴포넌트에서 useQuery를 통해 들어온 {data} 들은 global state 에 저장되는데, 이 global state를 apollo-cache-state 라고 한다. cache.modify 는 global state에 저장된 데이터를 직접 수정하는 것을 말한다.
global state 에는 fetchBoard: {} 과 같은 객체 형태로 데이터가 저장되어 있고, 각각의 객체들을 필드라고 부른다.

const onClickDelete = (boardId: string) => async () => {
    await deleteBoard({
      variables: { boardId },
      
      // variables 요청 후 cache 를 업데이트
      // cache, useQuery의 결과
      update(cache, { data }) {
        
        			   // data 안에 deleteBoard
        const deletedId = data.deleteBoard; // deleteBoard 를 실행하고 남은 return 값
        cache.modify({
          fields: {
            // 현재 페치보드 상태(prev)에서 삭제된 보드 지우기
            fetchBoards: (prev, {readField}) => {
              
              // _id가 배열로 저장된 prev에서 deletedId 와 같은 _id 제거
              // filter로 삭제된 _id와 다른 데이터만 남겨서 return 해주기
              // el._id 를 사용할 수 없기 때문에 readField로 el 에서 _id를 꺼내온다.
              const filteredPrev = prev.filter((el) => readField("_id", el) !== deletedId);
              return filteredPrev; 
            },
          }, // global state 를 수정했기 때문에 사용하는 모든 컴포넌트에서 업데이트 된다
        });
      }, 
    });
  };

cache.modify 를 이용한 삭제는 무한스크롤 페이지에서 주로 사용한다.

0개의 댓글