본문 바로가기

WINK-(Web & App)/React.js 스터디

[2024-2 React.js 스터디 ] 이서영 #2주차

반응형

useEffect

→ 마운트, 언마운트, 업데이트 할 시 작업 설정

 

첫 번째 파라미터 → 함수

두 번째 파라미터 → 배열( deps )

→ if deps 비움, 컴포넌트가 처음 나타날 때에만 useEffect에 등록한 함수 호출

 

cleanup 함수 

→ useEffect 함수 반환

→ deps 비움, 컴포넌트 사라질 때 cleanup 함수 호출

 

마운트 시 하는 작업

→ props 로 받은 값을 컴포넌트의 로컬 상태로 설정

→ 외부 API 요청

→ 라이브러리 사용

→ setInterval 반복작업, setTimeout 작업 예약

 

언마운트 시 하는 작업

→ setInterval, setTimeout 등록한 작업들 clear

→ 라이브러리 인스턴스 제거

 

 

deps

특정 값 넣기

→ 컴포넌트가 처음 마운트 될 때와 지정한 값 바뀔 때에도 호출

→ 언마운트시 호출, 바뀌기 직전에도 호출

 

규칙 

 useEffect 안에서 사용하는 상태, props 있으면 deps에 넣어야함 (안 그러면 최신 props, 상태 안 가르킴)

 

생략

→ 컴포넌트 리렌더링 될 때마다 호출

 

 

useMemo

→ 연산 값 재사용

첫 번째 파라미터 → 어떻게 연산할지 정의하는 함수

두 번째 파라미터 → deps 

함수 호출해서 값 연산해주는데 내용이 바뀌지 않는다면 이전에 연산한 값 재사용

 

useCallback

→ 함수 재사용 

컴포넌트에서 props 바뀌지 않았으면 Virtual DOM에 새로 렌더링 하지 않고

컴포넌트의 결과물을 재사용 하는 최적화 작업에서 재사용 필수

 

함수 안에 사용하는 상태 or props 존재

→ deps 배열 안에 포함 ( 안 지키면 최신값 참조 보장 x )

 

컴포넌트 렌더링 최적화 작업을 해주어야만 성능 최적화

 

 

React.memo

→ 컴포넌트 리렌더링 방지

props 변경 x, 리렌더링 방지해서 성능 최적화

export defualt React.memo(CreateUser);

 

간단!

 

users의 배열이 바뀔 때마다 onCreate, onToggle, onRemove 새로 만들어져서 리렌더링 됨

→ deps에 users가 들어있기 때문 

 

최적화하려면?

deps 에서 users 지우고 useState로 관리하는 users를 참조하지 않게 → 함수형 업데이트

 

useCallback, useMemo, React.memo 는 성능을 실제로 개선할 수 있는 상황에서만 하기

 

useReducer

→ 상태 업데이트 로직 분리( ex. 상태 업데이트 로직 컴포넌트 바깥에 작성, 다른 파일에 작성 후 불러와서 사용 )

첫 번째 파라미터 : reducer 함수

두 번째 파라미터 : 초기 상태

 

reducer

→ 현재 상태와 액션 객체를 파라미터로 받아와서 새로운 상태를 반환

function reducer(state, action) {
  // 새로운 상태를 만드는 로직
  // const nextState = 
  return nextState;
}

 

action

→ 업데이트를 위한 정보 가지고있음

→ 형태 자유

const [state, dispatch] = useReducer(reducer, initialState);

state 

→ 컴포넌트에서 사용 할 수 있는 상태

dispatch

→ 액션 발생 함수

 

useReducer vs useState

useReducer → 상태 구조 복잡해질 때

useState → 값이 단순한 숫자, 문자열, boolean

둘중 맘에 드는 거 쓰기..

 

 

커스텀 Hooks

→ 반복되는 로직 재사용

보통 use 라는 키워드로 시작하는 파일 생성 후 안에 함수  작성

Hooks 를 사용하여 원하는 기능 구현, 컴포넌트에서 사용하고 싶은 값 반환

 

Context API 

→ 전역 값 관리

const UserDispatch = React.createContext(null);

 

createContext → Context의 기본값 설정

Context 안에 Provider 컴포넌트를 통해 Context 값 정함 value 라는 값 설정 해주면 됨 

<UserDispatch.Provider value={dispatch}>...</UserDispatch.Provider>

 

Immer

더 쉬운 불변성 관리

→ 불변성을 신경쓰지 않으면서 업데이트 해주면 Immer 가 불변성 관리를 해줌

 

배열,객체를 업데이트 해야 할 때는 직접 수정 x, 불변성을 지켜주며 업데이트

연산자 또는 배열 내장함수로 할 수 있지만 구조가 까다로워지면 코드가 복잡해짐

const nextState = {
  ...state,
  posts: state.posts.map(post =>
    post.id === 1
      ? {
          ...post,
          comments: post.comments.concat({
            id: 3,
            text: '와'
          })
        }
      : post
  )
};
const nextState = produce(state, draft => {
  const post = draft.posts.find(post => post.id === 1);
  post.comments.push({
    id: 3,
    text: '와!'
  });
});

위보다 아래가 훨씬 깔끔

 

Immer 사용법

1. Immer 설치

2. immer 불러오기 (보통 produce라는 이름으로)

import produce from 'immer';

3. 첫번째 파라미터 : 수정하고싶은 상태

   두 번째 파라미터 : 어떻게 업데이트 하고 싶을지 정의하는 함수

 

Immer 라이브러리는 편하지만 무조건 사용하진 말고 필요할 때만, 성능적으로는 Immer 안 사용한 코드가 조금 더 빠름

 

 

 

클래스형 컴포넌트

import React, { Component } from 'react';

class Hello extends Component {
  render() {
    const { color, name, isSpecial } = this.props;
    return (
      <div style={{ color }}>
        {isSpecial && <b>*</b>}
        안녕하세요 {name}
      </div>
    );
  }
}

Hello.defaultProps = {
  name: '이름없음'
};

export default Hello;

render 메서드 반드시 있어야함. 

render 메서드에서 렌더링 할 JSX 반환

this.props로 props 조회

 

기존의 함수형 컴포넌트에서 작업을 실행하고 싶다면 컴포넌트 안에 선언하면 됐지만

클래스형 컴포넌트에서는 클래스 안에 커스텀 메서드 선언 (render 함수 내부에서 선언 가능, 일반적으로 안 함)

 

클래스형 컴포넌트의 state → 객체 형태

 

 

LifeCycle 메서드

→ 컴포넌트가 브라우저상에 나타나고, 업데이트되고, 사라지게 될 때 호출되는 메서드

→ 클래스형 컴포넌트에서만 사용가능

→ useEffect 랑 비슷함

 

변화 발생시 생명주기 메서드 호출됨

 

마운트될 때 발생하는 생명주기

  • constructor
  • getDerviedStateFromProps
  • render
  • componentDidMount

constructor

→ 컴포넌트의 생성자 메서드

 

getDerivedStateFromProps

→ props로 받은 것 state에 넣음

→ static 안에서 this 조회 x

→ null 반환시 아무 일 안 일어남

 

render

→ 컴포넌트 렌더링

 

componentDidmount

→ 컴포넌트의 첫 번째 렌더링 마친 후 호출됨

→ DOM을 사용해야하는 외부 라이브러리 연동

→ ajax 요청

→ DOM 속성 읽기, 직접 변경

 

 

업데이트 시 호출되는 생명주기 메서드

  • getDerivedStateFromProps
  • shouldComponentUpdate
  • render
  • getSnapshotBeforeUpdate
  • componentDidUpdate

getDeriveStateFromProps

→ props,  state 바뀌었을 때 호출됨 

 

shouldComponentUpdate

→ 컴포넌트 리렌더링 결정 

→ React.memo 랑 비슷

 

render

→ 컴포넌트가 화면에 어떤 내용을 표시할지를 정의

→ JSX 반환

 

getSnapshotBeforeUpdate

→ 컴포넌트에 변화가 일어나기 직전의 DOM 상태를 가져와서 특정값을 반환 하면 

다음 발생하게 되는 componentDidUpdate 함수에서 받아와서 사용 가능

 

componentDidUpdate

→ 리렌더링 마친 후 변화 반영 후 호출되는 메서드

→ 3번째 파라미터로 getSnapshotBeforeUpdate 에서 반환 값 조회 가능

 

 

언마운트

→ 컴포넌트가 화면에서 사라짐

 

componentWillUnmount

→ 컴포넌트가 화면에서 사라지기 직전 호출

 

 

 

componentDidCatch

→ 에러 잡아내기

→ 생명주기 메서드

첫 번째 파라미터 : 에러의 내용

두 번째 파라미터 : 에러가 발생한 위치 알려줌

 

에러가 발생하는 상황

→ props 제대로 설정 안 했을 때

→ props 설정 안 했을 때, 렌더링 과정에서 오류 발생

→ onToggle을 props로 안 넣어줄 때

 

 

리액트 개발 시 편리한 도구들

  • Prettier
  • ESLint
  • Snippet

 

Prettier 

→ 자동으로 코드 스타일 관리

→ CLI 통해 명령어 입력 사용 or 다양한 에디터와 연동 사용

→ 코드의 스타일을 커스터마이징

 

적용 방법

  • 명령어 사용
  • 에디터와 연동(권장)

파일 생성 후 에디터에서 Prettier 익스텐션 설치

→ Ctrl + , 누른 후 Format On Save 검색, 체크 ( 수동으로 하고 싶다면 F1 or Ctrl + Shift + P )

 

 

ESLint

→ js 문법 확인

 

Snippet

→ 자주 사용되는 코드의 단축어를 만들어 코드를 빠르게 생성

반응형