• 로그인시 받는 유저 데이터 recoil state 는 새로고침시 날아감
    1. 새로고침시 마다 유저 정보를 API 요청 → XXXXXX
    2. recoil state 를 persist
      • localStorage를 사용하는 방법이 있음
        • 새로고침시 localStorage에 저장해둔 값을 state에 다시 입력
        • localStorageEffect.js
        function localStorageEffect(key) {
        	return ({ setSelf, onSet }) => {
        		const savedValue = localStorage.getItem(key);
        		if (savedValue != null) {
        			setSelf(JSON.parse(savedValue));
        		} else {
        			// 로컬 스토리지에 저장된 값이 없으면 로그아웃 처리
        			localStorage.removeItem(key);
        			localStorage.removeItem('acccessToken');
        			localStorage.removeItem('refreshToken');
        			if (window.location.pathname !== '/login') {
        				window.location.href = '/login';
        			}
        		}
        
        		onSet((newValue, _, isReset) => {
        			isReset
        				? localStorage.removeItem(key)
        				: localStorage.setItem(key, JSON.stringify(newValue));
        		});
        	};
        }
        
        export default localStorageEffect;
        
        • store/recoil/index.js
        export const userInfoState = atom({
        	key: 'userInfoState',
        	default: {
        		id: 'M12341234',
        		name: '김철수',
        		accessLv: 3,
        	},
        	effects: [localStorageEffect('user')],
        });
        

 

1. 명령어로 구분

package.json에 script : start/build/test 각각의 스크립트가 있음

-> 배포시 build.gradle에 npm build 명령어가 들어있음

 

2. .env 파일에서 환경변수 사용

두개의 분리된 dotEnv 파일 생성

.env.development : 개발용 환경변수

.env.production : 상용 환경변수

 

원리) Creact-React-App으로 리액트를 만들고 npm 스크립트를 실행할 때 스크립트 명령어별로 env 파일의 적용 우선순위가 있다.

 

script 명령어 별 env 파일 우선순위

  • npm start : .env.development.local, .env.local, .env.development, .env
  • npm build : .env.production.local, .env.local, .env.production, .env
  • npm test : .env.test.local, .env.test, .env

 

3. 각각의 파일에서 REACT_APP으로 시작하는 baseURL 설정

//.env.development
REACT_APP_BASE_URL = http://localhost:3000
//.env.production
REACT_APP_BASE_URL = http:hello.com

 

5. axios config 또는 rootSaga 에서 설정한 환경변수 사용

baseURL : process.env.REACT_APP_BASE_URL

// rootSaga.js
axios.defaults.baseURL = process.env.REACT_APP_BASE_URL;

 

TODO

  • Router 아무 path 없을 때는 layout 구현, 그 안에 Route 구현
  • notFound 페이지 예외 처리 예정
  • Layout 에서 NavLink로 링크 구현
  • Outlet으로 랜더할 내용 받아줌
  • useParams로 parameter 받기

 

1. 사용할 페이지 간략 내용 views들 생성

  • /views/About.js
  • /views/About.js
  • /views/NotFound.js
  • /views/UserDetail.js
  • /views/Users.js
  • Layout은 조금 이따가

 

 

 

2. 레이아웃 담당할 Layout.js 작성

  • react-router-dom이 제공하는 NavLink, Outlet 사용
  • NavLink는 a태그 역할 링크 역할
  • Outlet은 Content가 담길 곳 명시하는 것 (react-router-dom내부 규칙)
// views/Layout.js

import { NavLink, Outlet } from 'react-router-dom';
import styled from 'styled-components';

const Nav = styled.nav`
    height : 100px;
    background-color : skyblue;
`

const Main = styled.main`
    display: flex;
`

const SideMenu = styled.div`
    min-width : 300px;
    min-height : 400px;
    border : 1px solid grey;
`

const Content = styled.div``

export default function Layout() {
    return (
        <>
            <Nav>
                <NavLink to="/">Home</NavLink>
                <NavLink to="/about">About</NavLink>
                <NavLink to="/user">Users</NavLink>
            </Nav>
            <Main>
                <SideMenu>사이드 메뉴</SideMenu>
                <Content>
                    {/* 각각 컴포넌트들이 보여질 곳 Outlet으로 받아줌 */}
                    <Outlet/>
                </Content>
            </Main>
        </>
    )
}

 

3. 위의 페이지들을 랜더링할 최상위 컴포넌트 App.js 작성

  • BrowserRouter로 전체라우팅 감싸기
  • Routes로 라우트들 감싸기
  • <Route element={<Layout/>}로 전체 레이아웃 설정
  • 전체 레이아웃 안에 이제, 랜더링될 페이지들이 Route 태그로 설정
  • 여기서 내부에 랜더링되는 페이지들이 위의 Layout.js 코드 속 Outlet에 표현된다.
  • user/3 과 같이 뒤에 파라미터로 id를 받는 경우는 user/:id로 표현
//App.js

import './App.css';
import { BrowserRouter, Route, Routes } from "react-router-dom";

import About from './views/About';
import Home from './views/Home';
import Users from './views/Users';
import UserDetail from './views/UserDetail';
import NotFound from './views/NotFound'
import Layout from './views/Layout';


function App() {
  return (
    <BrowserRouter>
      <Routes>
        {/* 아무 path 없으면 레이아웃 자동 만들어줌 */}
        <Route element={<Layout/>}>
          {/* 최초 슬래시로 갔을 때 */}
          <Route index element={<Home/>}/> 
          <Route path="about" element={<About/>}/>
          <Route path="user" element={<Users/>}/>
          <Route path="user/:id" element={<UserDetail/>}/>
          {/* 예외페이지 처리 */}
          <Route path="*" element={<NotFound/>}/>
        </Route>
      </Routes>
    </BrowserRouter>
  );
}

export default App;

 

4. UserDetail.js 에서 useParams를 사용하여 파라미터 받기

// views/UserDetail.js

import { useParams } from "react-router-dom"


export default function UserDetail() {
    let params = useParams();

    return <h1>UserDetail: { params.id }</h1>
}

 

[실행결과]

+ Recent posts