diary-최적화(memo)

2024. 1. 15. 05:19react-diary

<최적화 하는 이유>

App컴포넌트 새로고침 or 업데이트 시 자식 컴포넌트도 똑같이 실행됨

=> 불필요한 연산 발생

 

rendering : 코드를 화면에 그려주는 과정

=> 컴포넌트가 현재 props와 state의 상태에 기초해 UI를 어떻게 구성할지, 컴포넌트에게 작업을 요청하는 것

 

rerendering : 리액트에선 초기에 한번 렌더링을 진행하고, 그 이후에 특정 조건이 발생하면 다시 렌더링을 진행

 

< 발생 조건>

  • 내부 상태(state) 변경시
  • 부모에게 전달받은 값(props) 변경시
  • 중앙 상태값(Context value 혹은 redux store) 변경시
  • 부모 컴포넌트가 리렌더링 되는 경우

출처 : https://narup.tistory.com/272

 

mount / unmount : 화면에 데이터가 나타나는 것

컴포넌트가 나타남 = mount

삭제될 때 = unmount

 

import React from "react"; //최상단 React가 import되었는지 확인

const Deditor = () => {
	return (
    	<div>
        	sample
        </div>
    )
}

export default React.memo(Deditor); // React.memo(컴포넌트)

 

 

 

useEffect(() => {
        console.log('에디터 리랜더');
    })
 // 에디터 작동 시점 알아보기 위한 consloe

 

콘솔 창 확인 시

아래 사진처럼 업데이트 될 때마다 메시지 출력

이미지는 editor에 작성하는 사진이나 바로 아래 최적화 시킨 부분은 list에서 수정, 삭제 부분 최적화 됨

 

에디터 컴포넌트에서 App컴포넌트로부터 전달받은 saveDiary라는 props 존재

현재 문서 제일 아래쪽에서 에디터 컴포넌트를 메모화시킨다고 했으나 부모로부터 전달받은 props(saveDiary)가 업데이트 되면서 에디터 컴포넌트 또한 리렌더링 됨

=> 목록을 수정해도 콘솔창에 '에디터 리랜더' 메시지가 계속 출력

=> 최적화 위해서는 props로 전달받은 saveDiary의 연산이 최적화되도록 수정해야 함

  const saveDiary = (title, content, emotion) => {
    const createDate = new Date().getTime();
    const newItem = {
      id : diaryID.current,
      title,
      content,
      emotion,
      createDate
    }
    diaryID.current += 1;
    setData([newItem, ...data]);
  }
  // 최적화 전 saveDiary

 

 

의존성 배열?

useCallback(콜백함수, 의존성배열) : 현재 사용할 함수

: useCallback(useEffect, useMemo 등)함수 훅에 입력하는 두 번째 매개변수, 의존성 배열 내용 변경 시 부수 효과 함수가 실행됨

 

사용 목적

1. 훅의 재실행 조건 설정 : 의존성 배열에 포함된 값들이 변경될 때만 훅이 재실행되도록 조건 설정 = 불필요한 실행 방지

2. 최신 상태 유지 : 훅이 항상 최신 상태의 값 참조 가능 = 불필요한 연산 방지

3. 의존성 관리의 명확성 : 의존성 배열 사용 시 훅이 어떤 값에 의존하고 있는 지 명확하게 파악 O = 코드의 가독성 up, 의도하지 않은 의존성 관계 방지 O

 

예시)

useEffect(effect) //컴포넌트가 렌더링 될 때마다 호출

useEffect(effect, []) //첫 번째 렌더링 후에만 호출

useEffect(effect, [userId]) // 첫 번째 렌더링 후에 호출, 그 이후 userId 변경 될 때마다 호출

 

3번째 예시 경우 userId라는 값은 항상 렌더링과 관련된 값이어야 함

렌더링과 관련된 값이라는 것은 그 값이 변경되면 컴포넌트가 다시 렌더링 되는 지를 보고 알 수 있음

 

 

아래 내용에서 의존성 배열의 내용을 비워둘 시

일기가 저장될 때마다 빈배열의 상태에 새로운 일기 저장하게 만들어짐

=> 마지막 저장한 일기데이터 1개만 화면에 출력됨

 

아래 내용처럼 의존성 배열의 내용을 data로 작성 시

기존의 일기 데이터 + 새 일기 데이터

=> 삭제/추가와 같이 에디터에 상관 없는 동작 발생 시에 에디터 컴포넌트가 동작함 

 const saveDiary = useCallback((title, content, emotion) => {
    const createDate = new Date().getTime();
    const newItem = {
      id : diaryID.current,
      title,
      content,
      emotion,
      createDate
    }
    diaryID.current += 1;
    setData([newItem, ...data]);
  }, [data])
  // 최적화 후 : 괄호 확인 잘하기

 

 

그렇다면 내가 만들어야 하는 동작은?

 

- useCallback 사용해서 data의 상태 변하더라도  saveDiary가 재생성되지 않도록 해야 함

- saveDiary 통해 data의 상태가 변경된 것을 참고하기

 

const saveDiary = useCallback((title, content, emotion) => {
    const createDate = new Date().getTime();
    const newItem = {
      id : diaryID.current,
      title,
      content,
      emotion,
      createDate
    }
    diaryID.current += 1;
    // 
    // setData([newItem, ...data]);
    setData((data) => [newItem, ...data]) // setData 안에 함수 처리
  }, [])

 

'react-diary' 카테고리의 다른 글

react-diary-full  (0) 2024.01.17
react-router  (0) 2024.01.16
diay-기본  (1) 2024.01.14