📍src>store>auth-context.js
이 파일에서는 컴포넌트가 아닌 컴포넌트를 위한 컨텍스트를 만들기 때문에 kebab-case로 네이밍
import React from "react";
const AuthContext = React.createContext({
isLoggedIn: false,
});
export default AuthContext;
📍src>App.js
나중에 auth-context.js로 이동하여 효과적으로 관리할 수 있도록 전체 앱을 컨텍스트를 제공하는 컴포넌트로 감싼다.
AuthContext는 컴포넌트가 아니므로 .Provider를 추가하고 value를 올바르게 설정한다.
return (
✅<AuthContext.Provider
✅value={{
isLoggedIn: false,
// isLoggedIn이 변경될 때마다 리액트에 의해 업데이트 된다,
// 새로운 컨텍스트 객체는 리스닝 컴포넌트(소비하는 컴포넌트)로 전달된다
//✅ 로그아웃 핸들러도 이렇게 지정해준다
onLogout: logoutHandler,
}}
>
...
</AuthContext.Provider>
)
📍src>components>MainHeader>Navigation.js
컨텍스트를 리스닝 컴포넌트(=사용할 부분,소비할 부분)에 가져온다.
사용할 부분 전체를 AuthContext로 감싸는데 이 또한 컴포넌트가 아니기에 .Consumer
로 감싸준다. 내용을 중괄호로 묶고 함수를 만들어준다. props.isLoggedIn
-> ctx.isLoggedIn
으로 변경.
const Navigation = (props) => {
return (
✅<AuthContext.Consumer>
✅{(ctx) => {
return (
<nav className={classes.nav}>
<ul>
✅{ctx.isLoggedIn && ( ...
...
)}
</ul>
</nav>
);
}}
</AuthContext.Consumer>
);
};
export default Navigation;
useContext를 가져와서 AuthContext를 참조한다.(tapping) 상수로 만들어서 사용하기.
const Navigation = (props) => {
✅const ctx = useContext(AuthContext);
return (
<nav className={classes.nav}>
<ul>
✅{ctx.isLoggedIn && (
...
</ul>
</nav>
);
};
export default Navigation;
컴포넌트 간 정보 전달을 간편하게 만들어주어 긴 프롭 체인을 대체한다. 코드가 간결해지고 관리가 용이해진다.
컴포넌트 구성을 대체할 수 없으며 재사용이 불가능하다. 예를 들어 버튼 컴포넌트에서는 구성을 위해 프롭을 사용하는 것이 좋다. 컨텍스트는 특정 기능에 제한될 수 있기 떄문이다.
자주 변하는 상태에는 적합하지 않다. 초당 여러 번 업데이트가 발생하는 상황에서는 프롭이나 컨텍스트 대신 Redux와 같은 대안이 필요합니다.
모든 프롭을 컨텍스트로 대체하려고 하면 안된다. 프롭은 컴포넌트 구성에 있어서 여전히 중요하다.