React Hook 을 한마디로 요약하자면, class를 쓰지 않고, function에서 state 를 운용할 수 있는 기능.
즉, 기존에 함수형 컴포넌트에서 못하던 state 관리, 컴포넌트의 생명 주기 함수(ie, componentDidMount 등)를 이용할 수 있게 되었다.
그런데 만약 Component가 겹겹히 쌓여있고 props를 아주 많이 내려줘야되는 상황이라면 매 컴포넌트마다 state 관리하기란 비효율적이다. useReducer와 useContext는 이 상황을 효율적으로 관리하기 위해 사용된다.
왜 2개가 따로 있는가?
useContext는 간단한 React App에서 파워풀하게 적용할 때 적합할 수 있고
useReducer는 좀 더 커다란 App에서 states와 많은 변화들이 있을 때 적합할 수 있다.
이 post에서는 useContext를 확인해보자.
간단한 App에서 state를 파워풀하게 관리해보자.
user state를 보면서 확인해보자
// 📄App.js
...
function App(){
const [user, setUser] = useState({
name: "Seo"
})
return (
<>
<Screen user={user}/>
</>
);
}
...
// 📄Screen.js
...
const Screen = ({user}) => (
<div>
<Header user={user} />
<h1>First Screen</h1>
</div>
);
...
// 📄Header.js
...
const Header = ({user}) => (
<header>
<a href="#">Home</a> Hello, {user.name}!
</header>
);
...
user state를 props를 통해 내려주지만 중간에 사용되지도 않는 component에 넘겨줘야 하고 그걸 또 props로 넘겨줘야 하는 비효율적인 그림이 나온다.
context는 어플리케이션의 데이터 저장소이다.
// 📄context.js
export const UserContext = React.createContext();
const UserContextProvider = ({children}) => {
const [user, setUser] = useState({
name: "Seo",
loggedIn: false
});
const logUserIn = () => setUser({...user, loggedIn: true});
<UserContext.Provider value={user, fn: {logUserIn}}>
{children}
</UserContext.Provider>
}
export const useUser = () => {
const {user} = useContext(UserContext);
return user;
}
export const useFns = () => {
const {fn} = useContext(UserContext);
return fn;
}
export default UserContextProvider;
...
// 📄App.js
...
function App(){
return (
<UserContextProvider>
<Screen />
</UserContextProvider>
);
}
// 모든 component가 Provider태그 내에 위치하게 될 것이다.
// 이 로직이 context를 전역으로 사용될 수 있는 기본 rule이다.
...
// 📄Screen.js
...
const Screen = () => {
const {logUserIn} = useFns();
return (
<div>
<Header />
<h1>First Screen</h1>
<button onClick={logUserIn}>Log user in</button>
</div>
)};
...
// 📄Header.js
...
const Header = () => {
const {name, loggedIn} = useUser();
return (
<header>
<a href="#">Home</a>
<p>Hello, {name}, you are {loggedIn ? "logged in" : "anonymous"} </p>
</header>
)};
...
위 처럼 사용될 component에서만 useContext를 통해 state를 가져오고 사용할 수 있다.
당연히 context는 여러개 사용가능 하다.