5-1. 프로젝트 생성 및 리액트 라우터 / 리덕스 설정

프로젝트 생성

먼저 create-react-app 을 통하여 프로젝트를 생성하세요.

$ create-react-app heurm-client

핵심 라이브러리 설치

그리고, 해당 디렉토리로 이동하여 주요 모듈들을 설치하겠습니다.

$ yarn add react-router-dom react-redux redux redux-actions immutable styled-components open-color

NODE_PATH 적용

파일을 불러올 때 상대경로뿐만이 아닌 절대경로로도 파일을 불러 올 수 있도록 package.json 의 scripts 를 수정하세요.

package.json

  "scripts": {
    "start": "NODE_PATH=src react-scripts start",
    "build": "NODE_PATH=src react-scripts build",
    "test": "react-scripts test --env=jsdom",
    "eject": "react-scripts eject"
  }

값을 설정 한 다음, 개발서버를 실행하세요.

$ yarn start

.jsconfig.json 생성

절대 경로로 불러온 파일도, IDE 에서 자동완성이 제대로 되도록 .jsconfig.json 파일을 프로젝트 루트 디렉토리 만들어주겠습니다.

.jsconfig.json

{
    "compilerOptions": {
        "baseUrl": "./src"
    }
}

디렉토리 만들기

이번 프로젝트의 디렉토리 구조는 다음과 같습니다:

  • components: 프리젠테이셔널 컴포넌트들이 위치합니다
  • containers: 컨테이너 컴포넌트들이 위치합니다
  • lib: 프로젝트에서 필요한 함수들을 여기에 저장합니다
  • pages: 라우트 관련 컴포넌트들이 위치합니다
  • redux: 리덕스 관련 코드가 위치합니다

위 디렉토리들을 src 폴더 안에 미리 만들어주세요.

불필요한 파일 제거

다음 파일들을 제거하세요:

  • App.css
  • App.test.css
  • logo.svg

pages 디렉토리에 라우트 전용 컴포넌트 준비하기

라우트에서 사용 할 컴포넌트들을 미리 만들겠습니다. Auth 컴포넌트와 Home 컴포넌트를 만들고, 내용에는 텍스트를 그대로 렌더링하세요.

pages/Auth.js

import React, { Component } from 'react';

class Auth extends Component {
    render() {
        return (
            <div>
                Auth
            </div>
        );
    }
}

export default Auth;

pages/Home.js

import React, { Component } from 'react';

class Home extends Component {
    render() {
        return (
            <div>
                Home
            </div>
        );
    }
}

export default Home;

그 다음엔, 라우트 인덱스를 만들어줍니다.

/pages/index.js

export { default as Home } from './Home';
export { default as Auth } from './Auth';

라우트 설정

라우트를 App 컴포넌트에서 정의를 하도록 하겠습니다. 기존의 내용을 다 비우고, 새로 컴포넌트를 만들어서 다음과 같이 라우트들을 정의하세요.

src/App.js

import React, { Component } from 'react';
import { Route } from 'react-router-dom';
import { Home, Auth } from 'pages';

class App extends Component {
    render() {
        return (
            <div>
                <Route exact path="/" component={Home}/>
                <Route path="/auth" component={Auth}/>
            </div>
        );
    }
}

export default App;

이 다음에는, Root 컴포넌트를 만들어서 BrowserRouter 를 통해 라우터를 구성하세요.

src/Root.js

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

const Root = ({store}) => {
    return (
        <BrowserRouter>
            <Route path="/" component={App}/>
        </BrowserRouter>
    );
};

export default Root;

props 로 리덕스 스토어를 받도록 설정하였습니다. 추후 index.js 에서 리덕스 스토어를 생성 한 후 Root 컴포넌트에 전달을 해주고, Provider 컴포넌트를 이 파일에서 설정하도록 하겠습니다.

이제 프로젝트 엔트리 파일 (src/index.js) 에서 App 대신에 Root 를 정의하세요.

src/index.js

import React from 'react';
import ReactDOM from 'react-dom';
import Root from './Root';
import registerServiceWorker from './registerServiceWorker';
import './index.css';

ReactDOM.render(<Root />, document.getElementById('root'));
registerServiceWorker();

이제 브라우저에서 http://localhost:3000/ 페이지와 http://localhost:3000/auth 페이지를 열어서 Home / Auth 텍스트가 제대로 보여지는지 확인하세요.

리덕스 설정

우리는 리덕스쪽 코드는 ducks 구조를 따르도록 하겠습니다. redux 디렉토리에 modules 디렉토리를 만들고, base.js 파일을 생성하세요. 이 모듈은, 프로젝트의 기반에 관련된 상태를 관리합니다. 예를들어서, 헤더의 렌더링 여부 혹은 유저메뉴 나타남 여부 등을 관리하게됩니다.

앞으로 유저관련 모듈과 회원인증 관련 모듈도 만들게 됥 텐데 이번 섹션에선 일단 base 모듈을 먼저 만들어두겠습니다.

src/redux/modules/base.js

import { Map } from 'immutable';
import { handleActions, createAction } from 'redux-actions';

const SET_HEADER_VISIBILITY = 'base/SET_HEADER_VISIBILITY'; // 헤더 렌더링 여부 설정

export const setHeaderVisibility = createAction(SET_HEADER_VISIBILITY); // visible

const initialState = Map({
    header: Map({
        visible: true
    })
});

export default handleActions({
    [SET_HEADER_VISIBILITY]: (state, action) => state.setIn(['header', 'visible'], action.payload)
}, initialState);

그 다음엔, 모듈을 위한 인덱스를 만들겠습니다. 이 인덱스파일에선 combineReducers 를 통해 모듈안의 리듀서들을 하나로 합쳐주겠습니다. 지금은 비록 모듈이 이미 하나밖에 없긴 하지만, 추후 모듈들을 더 만들 것 입니다. 인덱스파일에서 리듀서들을 하나로 합쳐서 내보내세요.

src/redux/modules/index.js

import { combineReducers } from 'redux';
import base from './base';

export default combineReducers({
    base
});

이제, 스토어를 생성하는 함수를 만들어서 redux/configureStore.js 에 저장하도록 하겠습니다. 지금은 미들웨어와 react-hot-loader 를 아직 적용하지 않았으므로 다음과 같이 간단하게 코드를 작성하면 되며, 추후 다시 수정을 할 것 입니다.

src/redux/configureStore.js

import { createStore } from 'redux';

import modules from './modules';

// Todo: 미들웨어, react-hot-loader 적용
const configureStore = (initialState) => {
    const store = createStore(modules, window.__REDUX_DEVTOOLS_EXTENSION__ && window.__REDUX_DEVTOOLS_EXTENSION__());
    return store;
}

export default configureStore;

이제, 프로젝트 엔트리파일에서 스토어를 생성하고, Root 컴포넌트의 props 로 전달하겠습니다.

src/index.js

import React from 'react';
import ReactDOM from 'react-dom';
import Root from './Root';
import registerServiceWorker from './registerServiceWorker';
import './index.css';
import configureStore from 'redux/configureStore';

const store = configureStore();

ReactDOM.render(<Root store={store}/>, document.getElementById('root'));
registerServiceWorker();

그 다음엔 Root 컴포넌트를 열어서 Provider 를 최상위 컴포넌트로 설정하고 props 로 전달받은 store 를 넣으세요.

src/Root.js

import React from 'react';
import { BrowserRouter, Route } from 'react-router-dom';
import App from './App';
import { Provider } from 'react-redux';

const Root = ({store}) => {
    return (
        <Provider store={store}>
            <BrowserRouter>
                <Route path="/" component={App}/>
            </BrowserRouter>
        </Provider>
    );
};

export default Root;

자, 이제 리액트 라우터와 리덕스의 설정이 완료되었습니다. 리덕스 개발자 도구를 열어서 상태가 잘 정의되었는지 확인하세요.

results matching ""

    No results matching ""