props를 통해서 컴포넌트를 거쳐 데이터를 주고받으려면 불편함이 있다.
위 사진과 같은 구조에서 Login 이벤트를 Cart 컴포넌트로 직접 전송이 불가능 하기 때문에
이런식으로 props로 보내서 전송하게 된다.
하지만 이러한 구조는 프로젝트의 규모가 커질수록 불편하고 문제가 생기기 쉽다.
리액트는 이러한 문제를 해결할 수 있는 방법을 몇가지 가지고 있는데
1. Context API
2. Redux
와 같은 외부라이브러리가 있다.
오늘은 Context API에 대해 알아보려고 한다.
Context 란?
Context는 리액트 컴포넌트간에 어떠한 값을 공유할수 있게 해주는 기능이다. 주로 Context는 전역적(global)으로 필요한 값을 다룰 때 사용하는데, 꼭 전역적일 필요는 없다. Context를 단순히 "리액트 컴포넌트에서 Props가 아닌 또 다른 방식으로 컴포넌트간에 값을 전달하는 방법이다" 라고 접근을 하는 것이 좋다.
Context API 사용해보기
사용하기에 앞서 프로젝트 구조는 위와 같고 src 폴더 안에 store 폴더를 생성했다.
폴더 이름은 자유이지만 관습적으로 store, state, context와 같이 사용한다.
Context는 React 패키지에서 createContext() 라는 함수를 불러와서 만들 수있다.
import React from "react";
const AuthContext = React.createContext({
isLoggedIn: false, //로그인 인증
});
export default AuthContext;
Context 객체 안에는 Provider(공급자)라는 컴포넌트가 들어있고, 그 컴포넌트간에 공유하고자 하는 값을 value 라는 props로 설정하면 자식 컴포넌트들에서 해당 값에 바로 접근할 수 있다.
import AuthContext from "./store/auth-context";
function App() {
const [isLoggedIn, setIsLoggedIn] = useState(false);
return (
<React.Fragment>
<AuthContext.Provider value={{ isLoggedIn: isLoggedIn }}>
<MainHeader isAuthenticated={isLoggedIn} onLogout={logoutHandler} />
<main>
{!isLoggedIn && <Login onLogin={loginHandler} />}
{isLoggedIn && <Home onLogout={logoutHandler} />}
</main>
</AuthContext.Provider>
</React.Fragment>
);
}
이렇게 원하는 컴포넌트를 감싸주면 해당 컴포넌트의 자손 컴포넌트에서 context에 접근할 수 있게 된다.
Context 객체 안에는 Provider(공급자)뿐먄 아니라 Consumer(소비자)도 있는데, Consumer는 조금 다르게 작동한다.
자식으로 함수를 갖는데 인수로 컨텍스트 데이터(ctx)를 가져온다. { isLoggedIn: false } <= 바로 이 데이터.
const Navigation = (props) => {
return (
<AuthContext.Consumer>
{(ctx)=>{
<nav className={classes.nav}>
<ul>
{ctx.isLoggedIn && (
<li>
<a href="/">Users</a>
</li>
)}
{ctx.isLoggedIn && (
<li>
<a href="/">Admin</a>
</li>
)}
{ctx.isLoggedIn && (
<li>
<button onClick={props.onLogout}>Logout</button>
</li>
)}
</ul>
</nav>
}}
</AuthContext.Consumer>
);
};
그리고 이 함수에서 JSX 코드를 반환해야 한다.
useContext로 코드 개선
import React, { useContext } from "react";
import AuthContext from "../../store/auth-context";
import classes from "./Navigation.module.css";
const Navigation = (props) => {
const ctx = useContext(AuthContext); //포인터 전달
return (
<nav className={classes.nav}>
<ul>
{ctx.isLoggedIn && (
<li>
<a href="/">Users</a>
</li>
)}
{ctx.isLoggedIn && (
<li>
<a href="/">Admin</a>
</li>
)}
{ctx.isLoggedIn && (
<li>
<button onClick={props.onLogout}>Logout</button>
</li>
)}
</ul>
</nav>
);
};
export default Navigation;
useContext 훅을 이용해서 이렇게 쉽고 간단하게 코드를 개선할 수 있다. (이걸 더 추천)
Reference
'[개발 언어 & 프레임워크] > React' 카테고리의 다른 글
[React-Hooks] useReducer에 대해 알아보기(useState와 비교) (0) | 2022.11.05 |
---|---|
[React] Portal을 이용한 Modal 구현 (0) | 2022.10.28 |
React 설치 & 개발환경 세팅, JSX란? (0) | 2022.10.12 |
[React] 리액트 공부 일기(props란?) (0) | 2022.09.16 |
[React] 리액트 공부 일기 (프로젝트 생성, 컴포넌트 만들기, map과 useState) (0) | 2022.09.15 |