[React] Context API 사용을 통한 전역상태관리

jangwonyoon·2021년 8월 10일
0
post-thumbnail

🐥 웹 게임을 만들며 배우는 React 6강

강의 내용을 정리한 포스팅입니다.

📌 componentDidupdate

memo 또는 PureComponent는 불필요한 렌더링을 막기 위해서 자식 컴포넌트에서 사용해 준다.

📌 useMemo, useCallback

✅ useMemo

  • useMemo: 복잡한 함수 결과 값을 기억한다.
  • useRef: 일반 값을 기억한다.

hooks는 함수 컴포넌트 전체를 다시 실행하기때문에 임의로 만든 함수가 다시 실행되는 성능 저하측면이 있다. 이러한 부분을 useMemo 훅스를 사용하여 함수의 결과 값을 기억한다.

✅ useCallback

  • useCallback: 함수 자체를 기억하고 있는 것
  • 함수가 생성하는 것 자체가 너무 오래걸리는 경우는 함수 자체를 기억해둔다.
  • 부모 컴포넌트의 함수를 자식 컴포넌트에 넘기는 경우 useCallback을 사용하여 함수 컴포넌트 렌더링시 자주 변경되는 함수를 기억하여 성능저하를 최소화 시킬 수 있다.

**주의

기억을 너무 잘하기 때문에, useCallback에서 사용되는 state는 의존성 배열에 삽입하여준다.
그래야지 의존성배열의 요소가 변경되는 경우 useCallback이 다시 실행되어 새로운 상태 및 값으로 갱신하여준다.**

**참고

hooks는 선언해주는 순서가 중요하다.**

📌 hooks에 관한 팁

  • hooks는 무조건 최상위에 선언한다.

  • hooks는 조건문안에는 삽입하면 안된다.

  • 다른 hooks안에서 또 다른 hooks를 사용하면 안된다.

  • 반복문안에서는 useState를 넣어도 돌아는 가지만... 비추천한다. 최대한 hooks는 최상위로 빼서 실행순서가 같도록 작성해야한다.

  • useEffect는 의존성 배열에 요소를 넣지 않았을경우 componentDidMount 역할을 한다.

  • useEffect는 의존성 배열에 요소를 넣었을 경우 componentDidMount,componentDidUpdate 역할을 한다.

  • 만약에 componentDidUpdate 만 사용하고 싶은 경우, 아래와 같은 패턴 처리를 통해 해결할 수 있다.

    예시

    const mounted = useRef(false);
    
    useEffect(() => {
    	if (!mounted.current) {
    		mounted.current = true;
    	} else {
    		// ajax...
    	}
    }, [바뀌는 값]) // componentDidUpdate만, componentDidMount X

🐥 웹 게임을 만들며 배우는 React 7강

강의 내용을 정리한 포스팅입니다.

📌 useReducer

  • state를 관리하기 위해 useReducer를 사용한다.
  • 부모 컴포넌트에서 자식 컴포넌트로 props로 넘겨주는 부분에서도 단계가 많아지면 직관적으로 보기 쉽지 않기 때문에, 하나의 setState를 통해 처리할 수 있는 useReducer를 사용한다.
  • useReducer의 dispatch를 통해 상태를 바꾸는 행위는 비동기적으로 바뀐다.
  • 비동기적 상태에서 처리하기 위해서는 useEffect를 사용한다.

Tip

  • useReducer와 Context API로 리덕스를 흉내내어 상태 처리를 할 수 있고, 소규모 애플리케이션에서는 사용하기 좋다.
  • 하지만 비동기 처리와 규모가 큰 애플리케이션에서 대체하는 것은 어렵다.

성능 최적화 및 체크

  • ref와 useEffect를 사용하여 체크 및 해결한다.
  • React.memo, useMemo를 사용하여 해결한다.
  • useMemo는 값 뿐만아니라 컴포넌트 또한 기억할 수 있다.

🐥 웹 게임을 만들며 배우는 React 8강

📌 Context API

  • 성능 최적화하기에 정말 힘들다.

  • 그 이유는Context APIvalue 및 속성들이 매번 새롭게 렌더가 되고, context API를 사용하는 자식들 또한 매번 새롭게 리렌더링 되기 때문에 성능 개선을 위해 캐싱을 해야한다.

  • 이때 캐싱은 useMemo를 통해 진행한다.

    • 안 좋은 코드

      const MineSearch = () => {
        const [state, dispatch] = useReducer(reducer, initialState);
      
        const value = useMemo(() => ({ tableData: state.tableData, dispatch }), [state.tableData]);
      
        return (
      		<TableContext.Provider value={{ tableData: state.tableData, dispatch }}>
            <Form />
            <div>{state.timer}</div>
            <Table />
            <div>{state.result}</div>
          </TableContext.Provider>
        )
      }
    • 성능 개선 코드

      const MineSearch = () => {
        const [state, dispatch] = useReducer(reducer, initialState);
      
        const value = useMemo(() => ({ tableData: state.tableData, dispatch }), [state.tableData]);
      
        return (
          <TableContext.Provider value={value}>
            <Form />
            <div>{state.timer}</div>
            <Table />
            <div>{state.result}</div>
          </TableContext.Provider>
        )
      }
profile
어제보다 오늘 더 노력하는 프론트엔드 개발자

0개의 댓글