리액트 context란?
리액트 context는 앱에서 컴포넌트에게 props를 사용하지 않고 필요한 데이터를 넘겨주며 사용할 수 있게 해준다.
리액트 context는 컴포넌트들이 데이터(state)를 더 쉽게 공유할 수 있도록 해준다.
리액트 context를 사용해야 할 때
리액트 context는 앱의 모든 컴포넌트에서 사용할 수 있는 데이터를 전달할 때 유용하다.
데이터의 종류
데이터는 자주 업데이트 할 필요가 없는 리액트 context에 위치해야한다.
이유는 context는 전체적인 상태 관리를 위해 만들어진 시스템이 아니기 때문이다. context는 데이터를 쉽게 사용하기 위해 만들어졌다. 리액트 context는 리액트 컴포넌트를 위한 전역 변수와 같다고 생각하면 된다.
context가 해결해주는 문제
리액트 context는 props drilling을 막는데 도움을 준다.
Props drilling 이란 중첩된 여러 계층의 컴포넌트에게 props를 전달해주는 것을 의미한다.(해당 props를 사용하지 않는 컴포넌트들에게까지)
아래는 props drilling의 예시다. 이 앱에서는 모든 컴포넌트에 prop으로 전달된 theme 데이터에 접근할 수 있다. 하지만 Header와 같은 App의 직계 자식 컴포넌트 또한 props를 사용해 테마 데이터를 내려주어야한다.
ex) props drilling
export default function App({ theme }) {
return (
<>
<Header theme={theme} />
<Main theme={theme} />
<Sidebar theme={theme} />
<Footer theme={theme} />
</>
);
}
function Header({ theme }) {
return (
<>
<User theme={theme} />
<Login theme={theme} />
<Menu theme={theme} />
</>
);
}
이 예제의 문제는 theme prop을 사용하지 않는 많은 컴포넌트들에게까지 해당 prop을 내려주고 있다는 것이다.
Header 컴포넌트는 자식 컴포넌트에게 theme을 내려주기만 할 뿐 직접 필요로 하지 않는다. 다시 말해, User, Login, Menu 컴포넌트가 theme 데이터를 직접 사용하는게 더 나을 것이다.
이렇듯 모든 곳에 props를 사용하는 것을 우회할 수 있어 props drilling 문제를 피할 수 있는 것이 리액트 context의 장점이다.
context는 부모가 자식 컴포넌트에게 일일이 props를 넘겨주지 않고도 컴포넌트 트리 전체에 데이터를 전달할 수 있게 해준다.
useContext는 context를 좀 더 편하게 사용할 수 있도록 도와주는 hook이다.
createContext(initialValue)
createContext(initialValue)
ex) App.js
// App.js
import React, { useState, createContext } from "react";
import Mart from "./components/Mart";
export const AppContext = createContext(); // context생성
const initialValue = {
name: 'kim',
age: 20
};
return (
<>
<AppContext.Provider value={initialValue}> // Provider로 하위컴포넌트를 감싼다.
<Children />
</AppContext.Provider>
</>
);
}
export default App;
useContext(Context) → 자식컴포넌트에 작성
ex) Consumer 사용
//Children.js
// .Consumer 사용시
import React from "react";
import { AppContext } from "./App";
const Children = () => {
return (
<AppContext.Consumer> // .Consumer로 감싸준다.
{(initialValue) => (
<>
<h3>이름은 {initialValue.name}입니다.</h3>
<h3>나이는 {initialValue.age}입니다.</h3>
</>
)}
</AppContext.Consumer>
);
};
export default Children;
ex) useContext 사용
//Children.js
// useContext hook사용시
import React, { useContext } from "react";
import { AppContext } from "./App";
const Children = () => {
const initialValue = useContext(AppContext); // useContext hook사용.
return (
<>
<h3>이름은 {initialValue.name}입니다.</h3>
<h3>나이는 {initialValue.age}입니다.</h3>
</>
);
};
export default Children;