본문 바로가기
카테고리 없음

객체 얕은 복사/깊은 복사, 무한스크롤(복습 15일차)

by 제이엠_ 2022. 4. 22.

얕은 복사

const child1 = {
    name : "철수",
    age: 13,
    school: "다람쥐초등학교"
}
//undefined

const chill2 = {
    ...child1
}
//undefined

child2.name = "영희"
//'영희'

child2
//{name: '영희', age: 13, school: '다람쥐초등학교'}

child1
//{name: '철수', age: 13, school: '다람쥐초등학교'}

스프레드 연산자를 활용한 복사, 하지만 객체 안에 객체가 있다면 그것은 주소가 같아서 완전한 복사가 되지 않는다. 이러한 문제를 해결하는 것이 깊은 복사이다.

 

깊은 복사

const child1 = {
  name: {first : "Kim", last : "Jaemin"},
  age : 13, 
  school : "1"
}

const child2 = JSON.parse(JSON.stringify(child1))
child2.name.first = "choi"
child2.name.last = "younghee"


console.log (child1)
//
{
  name: { first: 'Kim', last: 'Jaemin' },
  age: 13,
  school: '1'
}

console.log (child2)
//
{
  name: { first: 'choi', last: 'younghee' },
  age: 13,
  school: '1'
}

깊은 복사는 JSON.stringify로 객체를 문자열로 바꿔준다. 그 이후에 JSON.parse로 바뀐 문자열을 다시 객체로 바꿔주면 된다. lodash를 해결할 수 있다. 이에 대해서는 아래 블로그로 공부를 해보자.

 

 

[JS] lodash로 깊은복사 해결

다음과 같이 .push()를 하게되면 해당 array로 잘 들어가야 한다.다음 코드의 결과물도 위의 결과물처럼 잘 적용되어 나온다고 생각했다.하지만,???..분명 '망고'로 삽입했는데 '딸기'가 두 개 들어갔

velog.io

 

실무에서 객체 복사

import { useState } from "react";
import { useMutation } from "@apollo/client";
import BoardWriteUI from "./BoardWrite.presenter";
import { CREATE_BOARD } from "./BoardWrite.queries";

export default function BoardWrite() {
  const [inputs, setInputs] = useState({ writer: "", title: "", contents: "" });

  const [qqq] = useMutation(CREATE_BOARD);

  const zzz = async () => {
    const result = await qqq({
      variables: { ...inputs },
    });
  };

  const onChangeInputs = (event) => {
    setInputs({
      ...inputs,
      [event.target.id]: event.target.value,
    });
  };

  return (
    <div>
      <div>스프레드연산자 연습!!</div>
      <input type="text" id="writer" onChange={onChangeInputs} />
      <input type="text" id="title" onChange={onChangeInputs} />
      <input type="text" id="contents" onChange={onChangeInputs} />
    </div>
  );
}

이걸 내가 배웠다는 게 새삼 놀랍다. 이렇게 효율적인 코드를 어렵다는 핑계로 무식하게 setState를 여러개 만들고 함수를 여러개 만들었다니. 이런 코드를 보니까 경이롭다는 느낌을 이제야 갖게 되니 아쉽다. onChangInputs에 event.target.id로만 쓰면 이게 텍스트 그대로 키 값이 되어 버리는데 우리는 event.target.id에 해당하는 writer, title, contents를 갖고 오기에 대괄호 []를 감싸주면 event.target.id에 해당하는 아이들로 키 값이 설정된다.

 

무한스크롤

fetchMore에 현재페이지 다음페이지를 요청해서 받아오고 fetchMoreResult에 값들이 저장해온다. 그 결과 fetchMoreResult의 값이 없으면 기존 데이터들을, 있으면 기존 데이터와 추가 데이터를 보여주도록 한다.

 

import { gql, useQuery } from "@apollo/client";
import InfiniteScroll from "react-infinite-scroller";

const FETCH_BOARDS = gql`
  query fetchBoards($page: Int) {
    fetchBoards(page: $page) {
      _id
      writer
      title
    }
  }
`;

export default function PaginationPage() {
  const { data, fetchMore } = useQuery(FETCH_BOARDS, {
    variables: { page: 1 },
  });

  const onLoadMore = () => {
    if (!data) return;

    fetchMore({
      variables: { page: Math.ceil(data.fetchBoards.length / 10) + 1 },
      updateQuery: (prev, { fetchMoreResult }) => {
        if (!fetchMoreResult.fetchBoards)
          return { fetchBoards: [...prev.fetchBoards] };

        return {
          fetchBoards: [...prev.fetchBoards, ...fetchMoreResult.fetchBoards],
        };
      },
    });
  };

  return (
    <InfiniteScroll pageStart={0} loadMore={onLoadMore} hasMore={true}>
      {data?.fetchBoards?.map((el) => (
        <div key={el._id}>
          <span>
            {el.title} {el.writer}
          </span>
        </div>
      ))}
    </InfiniteScroll>
  );
}

* 더 공부하기

react-infinite-scroller npm 으로 기능 더 보기

 

 

react-infinite-scroller

Infinite scroll component for React in ES6. Latest version: 1.2.6, last published: 9 days ago. Start using react-infinite-scroller in your project by running `npm i react-infinite-scroller`. There are 413 other projects in the npm registry using react-infi

www.npmjs.com

댓글