7. Context API

리리·2021년 8월 16일

TIL

목록 보기
21/22

일반적인 rn 어플의 경우, 데이터는 부모 → 자식 컴포넌트로 전달된다. 만일 데이터를 사용하는 컴포넌트가 많다면, 최상위 컴포넌트인 App 컴포넌트에서 상태를 관리하여 하위 컴포넌트 어디서 필요로 하든 props를 통해 전달할 수 있게 한다.

이렇게 하면 데이터 전달 방법이 매우 번거롭다. 또한, 자식 컴포넌트에서 부모로부터 받은 데이터를 변경할 수 없기 때문에 데이터를 전달받은 역순으로 App 컴포넌트에 데이터 변경 요청을 전달해야한다. App 컴포넌트에서 상태가 변경되면 다시 동일한 흐름으로 데이터를 사용하는 컴포넌트까지 전달되어야한다.

→ 최상위 컴포넌트에서 전역 상태를 관리하는 방식은 개발 단계 뿐만 아니라 유지보수에도 불편하다.

App→중간 컴포넌트→사용 컴포넌트 순서가 아니라 한번에 원하는 데이터를 받아와 사용할 수 있는 방법 = Context API를 이용해 Context를 생성해서 필요한 컴포넌트에서 데이터를 바로 받아올 수 있다.

Context API

context 생성

context를 생성하는 createContext함수는 파라미터에 생성되는 context의 기본값을 지정할 수 있다.

예시)
const Context = createContext(defaultValue);

Consumer

context 오브젝트는 consumer 컴포넌트와 provider 컴포넌트를 가지고 있다. consumer컴포넌트는 context의 내용을 읽고 사용한다.

consumer 컴포넌트는 상위 컴포넌트 중 가장 가까운 곳에 있는 provider 컴포넌트가 전달하는 데이터를 이용한다. 만일 상위 컴포넌트 중 provider 컴포넌트가 없다면 createContext 함수의 파라미터로 전달된 기본값을 사용한다.

compoents/User.js

const User = () => {
	return (
		<UserContext.Consumer>
			{value => <StyledText>Name: {value.name}</StyledText>}
		</UserContext.Consumer>
	);
};

contexts/User.js

import { createContext } from 'react';

const UserContext = createContext({ name: 'Beomjun Kim' });

export default UserContext;

Provider

provider 컴포넌트는 하위 컴포넌트에 context의 변화를 알리는 역할을 한다. provider 컴포넌트는 valueㄹ르 받아서 모든 하위 컴포넌트에 전달하고, 하위 컴포넌트는 provider 컴포넌트의 value가 변경될 때마다 다시 렌더링된다.

App.js

const App = () => {
	return (
		<UserContext.Provider value = {{ name: 'RN'}}>
			<Container>
				<User />
			</Container>
		</UserContext.Provider>
	);
};

app 컴포넌트를 provider 컴포넌트로 감쌌기 때문에 user 컴포넌트에서 사용된 consumer 컴포넌트는 더 이상 context의 기본값을 사용하지 않고 상위 컴포넌트인 provider 컴포넌트가 전달하는 데이터를 사용하도록 변경되었다.

Provider 컴포넌트로부터 value를 전달받는 하위 컴포넌트의 수에는 제한이 없다. 그러나, consumer 컴포넌트는 가장 가까운 provider 컴포넌트에서 값을 받는다.

그래서 App → A → B 에서 B가 consumer component이고 App, A 둘 다 provider 컴포넌트이면 A에서 값을 받아온다.

Context 수정하기

contexts/User.js

import React, { createContext, useState } from 'react';

const UserContext = createContext({
  user: { name: '' },
  dispatch: () => {},
});

//provider 컴포넌트 value에 전역적으로 관리할 상태 변수와 상태를 변경하는 함수를 함께 전달하는 UserProvider 컴포넌트를 생성했다. 
// 기존의 Provider 컴포넌트와 사용법이 동일하지만 하위에 있는 Consumer 컴포넌트의 자식 함수의 파라미터로 데이터뿐만 아니라 데이터를 변경할 수 있는 함수도 함께 전달한다. 
const UserProvider = ({ children }) => {
  const [name, setName] = useState('Beomjun Kim');

  const value = { user: { name }, dispatch: setName };
  return <UserContext.Provider value={value}>{children}</UserContext.Provider>;
};

const UserConsumer = UserContext.Consumer;

export { UserProvider, UserConsumer };
export default UserContext;

0개의 댓글