React/처음 만난 리액트(react)

Context란?

yooni825 2023. 10. 17. 22:48

Context

: 리액트 컴포넌트들 사이에서 데이터를 기존의 props를 통해 전달하는 방식 대신 컴포넌트 트리를 통해 곧바로 컴포넌트로 전달하는 새로운 방식을 제공함

-> 컨텍스트 사용하면 일일이 prop로 전달할 필요없이 데이터를 필요로 하는 컴포넌트에 곧바로 데이터를 전달할 수 있음

 

언제 Context를 사용해야 할까?

여러 개의 Component들이 접근해야 하는 데이터

: 사용자의 로그인 여부, 로그인 정보, UI 테마, 현재 언어 등

 

Context를 사용하면

: 기존 방식의 실제 데이터를 필요로 하는 컴포넌트까지의 깊이가 깊어질수록 복잡해짐을 개선할 수 있음

+ 전체적으로 간결하고 깔끔하며 직관적으로 바뀜

 

Context를 사용하기 전에 고려할 점

: 컴포넌트와 Context가 연동되면 재사용성이 떨어짐

-> 다른 레벨의 많은 컴포넌트가 데이터를 필요로 하는 경우가 아니라면 기존에 사용하던 방식대로 props를 통해 데이터를 전달하는 컴포넌트 컴포지션 방법이 더 적합함

 

 

 

Context API

 

React.createContext()

: Context를 사용하기 위해서 Context를 먼저 생성해야 함

const MyContext = React.createContext(기본값);

-> 함수의 파라미터로 기본 값을 넣어주면 됨 -> Context 객체가 생성됨

만약 상위 레벨에 매칭되는 provider가 없다면 기본값이 사용됨

기본값으로 undefined를 넣으면 기본값이 사용되지 않음

 

 

Context.Provider

: 하위 컴포넌트들이 해당 context의 데이터를 받을 수 있도록 설정해주어야 함

모든 context 객체는 provider라는 react 컴포넌트를 갖고 있음

context.provider 컴포넌트로 하위 컴포넌트들을 감싸주면 모든 하위 컴포넌트들이 해당 context 데이터에 접근 가능해짐

 

Provider 사용

<MyContext.Provider value={/* some value */} >

: provider 컴포넌트에는 value라는 prop이 있으며 이것은 provider 컴포넌트 하위에 있는 컴포넌트들에게 전달됨

 

Consuming Component

: 하위 컴포넌트들이 value 값을 사용하게 되는데 이 하위 컴포넌트들이 데이터를 소비한다는 뜻으로 부름

Context 값의 변화를 지켜보다가 만약 값이 변경되면 재랜더링됨

-> 하나의 Provider Component는 여러 개의 Consuming Component와 연결할 수 있으며 여러 개의 Provider Component는 중첩되어 사용될 수 있음

 

Provider value에서 주의해야 할 사항

Context는 재랜더링 여부를 결정할 때 레퍼런스 정보를 사용

-> Provider의 부모 컴포넌트가 재랜더링되었을 때 모든 하위 consumer 컴포넌트가 재랜더링됨

=> 이를 방지하기 위해서는 Value를 직접 넣는 것이 아닌 컴포넌트의 state로 옮기고 해당 state의 값을 넣어 주어야 함

 

Class.contextType

: 프로바이더 하위에 있는 class component에서 context의 데이터에 접근하기 위해 사용하는 것

ex) MyClass.contextType = MyContext;

: react.createContext 함수를 통해 생성된 context 객체가 대입될 수 있음, 이 속성을 사용하게 되면 this.context를 통해 상위에 있는 provider 중에서 가장 가까운 것의 값을 가져올 수 있음

 

Context.Consumer

: context의 데이터를 구독하는 component

함수 컴포넌트에서 context.Consumer를 사용하여 context를 구독할 수 있음

 

Context.Consumer 사용법

<MyContext.Consumer>
{value => /* 컨텍스트의 값에 따라서 컴포넌트들을 렌더링 */}
</MyContext.Consumer>

: 컴포넌트의 자식으로 오는 함수를 function as a child라 함

context.Consumer로 감싸주면 자식으로 들어간 함수가 현재 context의 value를 받아서 react node로 리턴하게 됨

 

function as a child를 사용하는 방법

// children이라는 prop을 직접 선언하는 방식
<Profile children = {name => <p>이름: {name} </p>} />

//Profile 컴포넌트로 감싸서 children으로 만드는 방식
<Profile>{name => <p>이름: {name}</p>} </Profile>

 

 

Context.displayName

: 문자열 속성 / 크롬의 React 개발자 도구에서 context의 Provider나 Consumer를 표시할 때 displayName을 함께 표시해줌

 

여러 개의 Context 사용하기

: context.provider를 중첩해서 사용하는 방식으로 구현 가능

2개 또는 그 이상의 contexte 값이 자주 함께 사용될 경우,

모든 값을 한번에 제공해주는 별도의 render prop component를 직접 만드는 것을 고려하는 게 좋음

 

useContext()

: 훅 / 함수 컴포넌트에서 context를 쉽게 사용할 수 있게 해줌

 

useContext() Hook을 사용한 예시

function MyComponent(props) {
	const value = useContext(MyContext);
		return (
        ...
)}

-> react.createContext 함수 호출로 생성된 컨텍스트 객체를 인자로 받아서 현재 컨텍스트의 값을 리턴함

=> useContextHook을 사용하면 컨텍스트의 값을 다른 방식과 동일하게 컴포넌트 트리 상에서 가장 가까운 상위 provider로부터 받아오게 됨

 

if, context의 값이 변경되면 변경된 값과 함께 useContextHook을 사용하는 컴포넌트가 재렌더링됨

+ useContextHook을 사용할 때는 파라미터로 context 객체를 넣어줘야 함!

 

//올바른 사용법
useContext(MyContext);

//잘못된 사용법
useContext(MyContext.Consumer);
useContext(MyContext.Provider);