React Hook의 useContext와 useMemo

캡틴 노드랭크·2021년 8월 15일
0

React

목록 보기
7/7

React로 앱을 개발하다보면 어떤 컴포넌트에게 Props로 데이터를 전달 해줘야할 때가 있다.

App.js를 최상위 컴포넌트로 두고, 다른 두개의 하위컴포넌트에게 데이터를 props로 전달해준다면 아래와 같을 것이다.

App.js

function App () {
  return (
  <div>
    <AC datas={propsA}/>
    <BC datas={propsB}/>
  </div>
  )
}

AC.js

function AC ({datas}) {
  return (
  <div>
	    {datas}	
  </div>
  )
}

BC.js

function BC ({datas}) {
  return (
  <div>
    {datas}
  </div>
  )
}

작은 프로젝트의 경우 별 문제는 없겠지만, 규모가 커져 하위컴포넌트가 늘어나게 되는데, 이렇게 Level이 증가하게 되고 데이터량도 많아져 더욱 난감해진다.

또 하위 컴포넌트마다 props를 일일히 작성해줘야하므로, 유지보수 및 개발 난이도도 증가하게된다. 이렇게 계속 컴포넌트를 뚫고가야 하기 때문에 props drilling패턴이라는 명칭도 붙게되는데

이런 문제를 위해 전역에서 데이터를 관리해주는 redux,MobX 라이브러리로 데이터나 상태를 전역store에 관리하여 해결했었다. 이번에는 React팀이 다시 살려낸 Context API에 대해 알아보자.

React.createContext와 Hook

React.createContext(defaultValue) 로 생성한 Context 객체를 상징하는 변수에 담아 사용한다.

const ContextA = React.creatContext(defaultValue)

그리고 이 Context 객체를 호출했으니 두 친구가 따라오는데 바로 ProviderConsumer이다.

  • Provider는 Context에 우리가 설정한 값을 담거나 변경 사항을 자손들에게 제공해줄 수 있다.
render() {
  return(
  <ContextA.provider value={value}>
    {value}
 </ContextA.Provider value={value}>
 )
}
  • Consumer는 Context의 변경된 값을 감지하고, 컨텍스트를 업데이트 해야하는 경우 사용한다.`

이 함수에는 context value를 매개변수로 받아 React node를 반환한다.

컴포넌트 트리에서 가장 가까운 Provider의 value를 받으며, 그렇지 않을경우 createContext()defaultValue를 받게된다.

<OtherContext.Consumer>
  {(value) => /* render something based on the context value */}

출처:  [Code Playground]}
</OtherContext.Consumer>

class에서는 이런식으로 태그를 붙여 사용했었지만 함수형 컴포넌트에서 Context를 사용하기위해 UseContext가 등장하였다.

import React, {createContext, useContext} from 'react'

해당 기능을 사용하기위해 모듈을 불러온다.

const contextName1 = createContext(defaultvalue);
const contextName2 = createContext();

useContext를 가져온다. 이때 useContext의 인수는 반드시 컨텍스트 객체여야한다.

const myTheme = useContext(contextName1)
const otherContext = useContext(contextName2)

주의사항

provider는 Context를 사용하기 위해서는 이 Context에 영향받는 하위 컴포넌트들의 집합인 상위 컴포넌트에서 감싸줘야한다.

예를들면,

  1. 하위 컴포넌트 Proivder생성

SampleProvider.js

const TestContext = createContext();

function SampleProvider ({children}) {
   const [ aValue, setAValue ] = useState("")
   
   const values = {
    aValue,
    setAValue
   }
  return(
   <TestContext.Provider value={value}>
    {datas}
   </TestContext.Provider value={value}>
  )
}

A.js

import SampleProvider from "./SampleProvider";

function A() {
 
 return (
   <div>
     <SampleProvider>
      <기타 영향 받을 컴포넌트 1/>
      <기타 영향 받을 컴포넌트 2/>
      <기타 영향 받을 컴포넌트 3/>
     </SampleProvider>
   </div>
  )
}

provider 컴포넌트를 만들때 그 인자값은 반드시 children이다.

SampleProvider 라는 Provider 기능을 가진 구성요소를 생성했을때 propschildren을 받는다.

.Consumer 혹은 UseContext는 반드시 Context 객체를 인수로 받아야하며, Provider에 제공된 값(value)이 달라지게 하기 위해 사용한다.

import { TestContext } from "./SampleProvider";

function SampleConsumer ({data1, data2}) {
   const { aValue, setAValue } = useContext(TestContext);
   
   const handlClick = () => {
      setAValue(data1)
   }

  return(
   <div>
     <BB a={aValue} onClick={handleClick} >
      {datas2}
     </BB>
   </div>
  )
}

useMemo

기존에 UseEffec()state가 바뀔때마다 다시 렌더링 되는 특징을 가진 생명주기의 기능으로 사용한다. 그러나 다시 렌더링하는 과정에서 필요 없는 내용들을 포함하여 불러오는데,

자원낭비, 규모에 따라 찾아오는 성능 저하 문제로 특정 상황에서만 동작 을하는 Hook함수가 바로 useMemo이다.

const memoizedValue = useMemo(() => computeExpensiveValue(a, b), [a, b]);

여기서 두번째 배열을 보면 다른 Hook함수와 마찬가지로 두번쨰의 배열은 a,b의 의존성을 띄어 이 두가지 state가 변경 될 때에만 함수가 호출된다.

ref: React 공식 페이지, 때늦은 Context API,제로초,Understand Context API

profile
다시 처음부터 천천히... 급할필요가 없다.

0개의 댓글