[TIL] 프론트엔드 22.05.26

KIKO·2022년 5월 26일
0

TIL

목록 보기
21/23
post-thumbnail

📚 공부한 내용

React에 style 적용하기

1. style sheet

css, scss 등의 별도 파일로 적용

2. inline style

컴포넌트 태그 안에 style 속성을 지정, props를 이용한 동적 적용이 가능.

3. CSS in JS - Emotion

외부 라이브러리를 사용하는 방식 emotion 등이 있다.

useMemo

목적

컴포넌트 리렌더링 발생 상황은 다음과 같다.
1. 자신의 상태가 변경될 때 (함수 컴포넌트의 경우만)
2. 부모 컴포넌트로 부터 받는 props가 변경될 때
3. 부모 컴포넌트의 상태가 변경될 때
컴포넌트가 리렌더링되면 말 그대로 JSX를 반환하는 함수를 다시 실행하는 것이고 이 과정에서 불필요한 동작이 있을 수 있다. 이렇게 불필요한 코드 실행을 방지하기 위해서 사용할 수 있는 Hook이 useMemo이다.

사용

useEffect와 비슷하게 감시할 인자와, 그 인자가 변경될 때 실행할 함수를 매개변수로 대입한다.

코드
function App() {
  const [data, setData] = useState(0)
  return (
    <div className="App">
      <button onClick={() => setData(data + 1)}>
        Change Data
      </button>
      <Component data={data}>
    </div>
  )
}
function calculate(data) {
  let result = data
  //매우매우 복잡하고 오래걸리는 연산
  return result
}
function Component({ data }) {
  // data의 값이 변경되었을 때만 'calculate' 함수가 실행된다.
  const result = useMemo(calculate(data), [data])
  return (
    <div>
      {result}
    </div>
  )
}

위 처럼 Component의 result에 영향을 주는 data값에 변경이 있을 경우만 calculation함수가 실행되게 할 수 있으며, 이를 통해서 불필요한 동작을 막을 수 있다.

React.memo

목적

위에서 설명했듯 부모 컴포넌트의 상태가 변경될 때 자식 컴포넌트의 리렌더링이 발생한다. useMemo를 사용해서 일부 최적화가 가능하지만 리렌더링 자체를 막을 수는 없었다. 이 경우 React.memo를 사용하여 부모 컴포넌트의 상태 변경시 리렌더링을 막을 수 있다.

사용

JSX를 반환하는 함수를 React.memo()로 감싸서 사용한다.

코드
import React from 'react'
const Memo = React.memo(({ memo }) => {
  console.log('memo rendered')
  return <div>Memo: {memo}</div>
})
export default Memo
import React from 'react'
function Memo({ memo }) {
  console.log('memo rendered')
  return <div>Memo: {memo}</div>
}
export default React.memo(Memo)

위 처럼 React.memo를 사용해서 props의 변화가 있을 경우만 렌더링이 진행되도록 할 수 있다. 하지만 props의 변화 감지가 얕은 비교를 통해서 이루어지므로 참조형 데이터가 props인 경우 이를 비교하여 true, false 값을 반환하는 비교 함수를 두 번째 인자에 추가할 수 있다.
관련 문서

useCallback

함수의 재정의

useCallback의 사용 목적을 알기 위해서 리렌더링 동작에서 함수의 재정의 개념을 이해해야 한다. 이에 대해서 내가 이해한대로 정리하면 아래와 같다.

위의 예시 코드에서 Childe 컴포넌트는 렌더링시에 메세지를 출력한다
(f12를 누르면 나오는 개발도구의 콘솔창에 출력된다).
Child 컴포넌트는 React.memo를 사용해서 부모 컴포넌트의 상태가 변경되어도 리렌더링이 발생하지 않아야 하지만 Change State 버튼을 클릭해 부모 컴포넌트인 App의 상태를 변경하면 메세지가 출력된다. 이는 다음과 같은 일련의 과정 때문이다.

  1. App의 상태가 변경되어 리렌더링
  2. App의 리렌더링 과정에서 onClick 함수가 재정의
  3. onClick 함수는 Child의 props이므로 Child가 리렌더링

즉, App이 리렌더링 될 때 onClick 함수는 변경이 없어보이지만, 이름과 내용이 동일한 또 다른 함수로 대체되는 것이다.

목적

위의 예시에서 알 수 있듯이 자식 컴포넌트에 props로 callback 함수를 사용하면 실행 내용에 변경이 없어도 불필요한 렌더링이 발생할 수 있다. 이를 방지하기 위해서 useCallback을 사용한다.

사용

렌더링 시에 재정의를 막을 함수와 의존성 배열을 매개변수로 입력한다.

function App() {
  const [state, setState] = useState(0)
  const onClick = useCallback(() => console.log('click'), [])
  return (
    <div className="App">
      <h2> App </h2>
      <p>state: {state}</p>
      <button onClick={() => setState(state + 1)}>Change State</button>
      <Child onClick={onClick}/>
    </div>
  );
};

Storybook

공식문서
UI를 분리하여 관리할 수 있는 라이브러리에 대해서 간단한 예제를 직접 실행해봤다. 프로젝트 진행에 있어 고려할만한 라이브러리였다.


🧐느낀점

정리를 하면서 내가 이해한 것을 설명하는 것이 가장 어렵다는 것을 새삼 느낀다. 다른 사람이 봤을 때 이해하기 쉽게 정리하고 싶었는데, 뭔가 내용만 길어진 느낌이다.


Reference

  1. 프로그래머스 프론트엔드 데브코스
  2. React 공식 문서
    https://ko.reactjs.org/docs/getting-started.html
profile
개발자로 발돋움

0개의 댓글