반응형
React에서 User Data를 관리하기 위해 ContextAPI를 사용해보았다.
import { Outlet } from 'react-router-dom';
import AuthContextProvider from './components/context/AuthContext';
import Navbar from './components/Navbar';
function App() {
return (
<AuthContextProvider>
<Navbar />
<Outlet />
</AuthContextProvider>
);
}
export default App;
최상단의 App.js 파일은 아래와 같다
내가 사용한 ContextAPI코드는 AuthContext.js에 담겨져있다
App 컴포넌트에서 AuthContextProvider로 감싸서 ContextAPI를 사용하면 된다.
import { createContext, useContext, useEffect, useState } from 'react';
import { login, logout, onUserStateChange } from '../../auth/firebaseAuth';
const AuthContext = createContext();
export default function AuthContextProvider({ children }) {
const [user, setUser] = useState();
useEffect(() => {
onUserStateChange((user) => {
console.log(user);
setUser(user);
});
}, []);
return <AuthContext.Provider value={{ user, login, logout }}>{children}</AuthContext.Provider>;
}
export function useAuthContext() {
return useContext(AuthContext);
}
src/components/context/AuthContext.jsx
파일이다.
이 파일에서 ContextAPI를 사용하고 있다
우선 createContext() 함수를 사용해서 AuthContext를 만들어준다.
AuthContext.Provider의 value로 user데이터와 firebase login, logout 함수를 인자로 주었다.
이제 이 ContextAPI가 감싸진 코드에서는 자유자재로 user, login, logout를 호출해서 사용이 가능하다.
기존의 Navbar.jsx 코드를 이제 더 깔끔하게 작성할 수 있게 되었다.
처음에는 이랬던 코드를
import React from 'react';
import { Link } from 'react-router-dom';
import { FiShoppingBag } from 'react-icons/fi';
import { BsFillPencilFill } from 'react-icons/bs';
import { login, logout, onUserStateChange } from '../auth/firebaseAuth';
import { useState, useEffect } from 'react';
import Button from './Button';
import User from './User';
export default function Navbar() {
const [user, setUser] = useState();
useEffect(() => {
// login session check!
onUserStateChange((user) => {
console.log(user);
setUser(user);
});
}, []);
return (
<header className="flex justify-between border-b border-gray-300 p-2 font-semibold">
<Link to="/" className="flex items-center text-4xl text-brand">
<FiShoppingBag />
<h1>Shoppy</h1>
</Link>
<nav className="flex items-center gap-4">
<Link to="/products">Products</Link>
<Link to="/carts">Carts</Link>
{user?.isAdmin && (
<Link to="/products/new" className="text-2xl">
<BsFillPencilFill />
</Link>
)}
{user && <User user={user} />}
{!user && <Button onClick={login} text={'Login'}></Button>}
{user && <Button onClick={logout} text={'Logout'}></Button>}
</nav>
</header>
);
}
아래와 같이 가독성 좋게 표현이 가능해졌다. 두둥!
useEffect함수를 contextAPI로 빼주었고 useAuthContext를 import해서 user데이터와 login, logout 함수를 가져올 수 있다.
다소 복잡해보이지만 제일 심플한 로직이다.
ContextAPI는 기본적으로 잘 다룰 줄 알아야 React에서 data를 좀 다뤄봤다고 이야기 할 수 있을 듯
import React from 'react';
import { Link } from 'react-router-dom';
import { FiShoppingBag } from 'react-icons/fi';
import { BsFillPencilFill } from 'react-icons/bs';
import Button from './Button';
import User from './User';
import { useAuthContext } from './context/AuthContext';
export default function Navbar() {
const { user, login, logout } = useAuthContext();
return (
<header className="flex justify-between border-b border-gray-300 p-2 font-semibold">
<Link to="/" className="flex items-center text-4xl text-brand">
<FiShoppingBag />
<h1>Shoppy</h1>
</Link>
<nav className="flex items-center gap-4">
<Link to="/products">Products</Link>
<Link to="/carts">Carts</Link>
{user?.isAdmin && (
<Link to="/products/new" className="text-2xl">
<BsFillPencilFill />
</Link>
)}
{user && <User user={user} />}
{!user && <Button onClick={login} text={'Login'}></Button>}
{user && <Button onClick={logout} text={'Logout'}></Button>}
</nav>
</header>
);
}
그럼 20000!
반응형