elice/WIL
[week_09] React 문법 | React-Router-Dom v6, useReducer, useContext
건망디
2022. 3. 13. 17:02
1. React-Router-Dom 라이브러리 v6
1-1. Routes, element
Router ➡ Routes ➡ Route 구조로 구현하고, element props를 사용해서 렌더링할 컴포넌트를 전달한다.
import { BrowserRouter as Router, Routes, Route } from "react-router-dom";
function App() {
return (
<Router>
<Routes>
<Route path="/" element={<Portfolio />} />
<Route path="/login" element={<LoginForm />} />
<Route path="/register" element={<RegisterForm />} />
</Routes>
</Router>
);
}
1-2. useNavigate
특정 경로로 이동할 때는 useNavigate 훅을 사용한다.
const navigate = useNavigate()
navigate("/login")
navigate("/login", {replace: true})
1-3. path="*"
SPA 라우팅에 걸러지지 않는 링크의 경우 path="*"를 사용한다.
<Router>
<Routes>
<Route path="/" element={<Portfolio />} />
<Route path="/login" element={<LoginForm />} />
<Route path="/register" element={<RegisterForm />} />
<Route path="*" element={<NotFound />} />
</Routes>
</Router>
위 예시의 경우, 사용자가 접속한 url이 ~/, ~/login, ~/register 중 하나가 아닐때 자동으로 NotFound 컴포넌트를 렌더링하도록 만든다.
2. useReducer
2-1. useReducer 문법
✨ useReducer의 규칙
1️⃣ state, reducer, dispatch, action, action.type, action.payload
2️⃣ action을 dispatch하면 state가 바뀐다.
3️⃣ action.type의 종류에 따라 reducer가 state를 바꾼다.
4️⃣ reducer가 state를 바꿀 때, action.payload의 데이터를 사용한다.
2-2. useReducer 활용 방법
1) reducer 함수 생성
export function loginReducer(userState, action) {
switch (action.type) {
case "LOGIN_SUCCESS":
return {
...userState,
user: action.payload,
};
case "LOGOUT":
return {
...userState,
user: null,
};
default:
return userState;
}
}
2) useReducer를 사용해서 상태, dispatch 생성
const [userState, dispatch] = useReducer(loginReducer, {user: null});
3) 로그인 시 dispatch 사용: dispatch 함수를 실행해서, 객체(action)을 reducer 함수로 보냄
const res = await Api.post("user/login", { email, password, });
const user = res.data;
dispatch({ type: "LOGIN_SUCCESS", payload: user, });
3. useContext
1) createContext로 Context를 생성하고, 해당 Context를 export
export const UserStateContext = createContext(null);
export const DispatchContext = createContext(null);
2) Context.provider 컴포넌트로 다른 컴포넌트를 감싼다.
<Context.provider value={다른 컴포넌트에서 쓸 변수}>
<다른 컴포넌트 />
</Context.provider>
function App() {
// useReducer 훅을 통해 userState 상태와 dispatch함수를 생성함.
const [userState, dispatch] = useReducer(loginReducer, {
user: null,
});
return (
<DispatchContext.Provider value={dispatch}>
<UserStateContext.Provider value={userState}>
<Router>
<Header />
<Routes>
<Route path="/login" element={<LoginForm />} />
</Routes>
</Router>
</UserStateContext.Provider>
</DispatchContext.Provider>
);
}
3) 다른 컴포넌트에서 context를 import하고, useContext를 사용한다.
import { DispatchContext } from "App";
function LoginForm() {
const dispatch = useContext(DispatchContext);
const handleSubmit = async (e) => {
e.preventDefault();
try {
// "user/login" 엔드포인트로 post요청함.
const res = await Api.post("user/login", {
email,
password,
});
// 유저 정보는 response의 data임.
const user = res.data;
// dispatch 함수를 이용해 로그인 성공 상태로 만듦.
dispatch({
type: "LOGIN_SUCCESS",
payload: user,
});
return (
<div></div>
)
}