일안하고블로그

[ React ] Redux 시작하기 / 기초 -1 본문

React/State Menagement

[ React ] Redux 시작하기 / 기초 -1

대한93 2018. 7. 17. 10:27



Redux

작업 파일 다운로드는 여기를 클릭해주세요.

FaceBook 팀이 만든 Javascript 라이브러리입니다. 

React만 사용해도 어플리케이션을 개발 할 수 있으나, 어플리케이션의 규모가 커지고 복잡해지면서, state관리가 복잡해 졌습니다. Redux는  복잡한 state관리를 단순하게 처리할 수 있게 도와줍니다.

 


Redux의 3원칙- 지금 꼭 이해할 필요는 없어요.

1. 모든 상태는 하나의 Store로 구성

2. 상태는 읽기전용이다.

3. 변화 함수는 순수 함수로 작성해야한다.

1. Flux 와 차이점인데, 쉽게 한개의 Store라는 것을 관리한다고 보면 됩니다. 

2. 상태(State)를 변경하려면 action이라는 객체를 전달하는 방법 뿐입니다. action 개념은 하단에서 예시를 보면서 이해하면 됩니다.

3. 순수 reducer로 작성해야 합니다. reducer도 하단에 작업을 진행하면서 이해하시면 됩니다. 



우선, create-react-app으로 프로젝트를 만듭니다.

$ create-react-app redux-test

설치가 완료 되었으면, 프로젝트 폴더 이동

$ cd redux-test

프로젝트 이동후, 실행.

$ yarn start

화면이 나오면 성공입니다.

다음으로, Command 혹은 Bash 창에서 start 프로젝트를 중지 합니다.

정지 후, redux와 react-redux 패키지를 설정합니다.

$ yarn add redux react-redux

간단한 설정을 끝냈습니다.

사용 하시는 Tool을 열고 만드신 폴더를 열어주세요.

기본적으로 폴더는 아래 이미지 처럼 되어있을 거에요.




화면에서 몇개의 파일을 제거합니다. 


  •  /src/App.js 
  •  /src/App.css
  •  /src/App.test.css
  •  /src/logo.svg 


src 디렉토리에 폴더를 추가합니다. 


  • actions : ActionType , action Constructor
  • components : view 담당 , Presentational Component
  • containers : store에 접근 하는 Container Component
  • reducers : store의 기본상태와 update를 담당하는 reducer file
  • utils : 일부 공용 File


사진처럼 우선 폴더만 만들어주세요 . 

지금 부터 redux를 활용해서 하나의 어플리케이션을 만들 것입니다.


어플리케이션 이름: 숫자 더하기

목표 : 버튼을 누른 만큼 보이기


삭제 했던 App.js를 추가합니다. 

src/containers/App.js

import React, { Component } from 'react';

class App extends Component {
render() {
return (
<div>
숫자 카운트
</div>
);
}
}

export default App;

App.js의 경로가 바뀌었으니, index.js를 수정합니다.

src/index.js

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

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

components 폴더에 파일을 추가합니다. 

src/components/PresentationalCount.js

import React from 'react';
import PropTypes from 'prop-types'; //props 기본 설정

const PresentationalCount = ({ number, onIncrement }) => {
return (
<div>
<div>{number}</div>
<button onClick={onIncrement}>더하기</button>
</div>
);
};
PresentationalCount.propTypes = {
number: PropTypes.number,
onIncrement: PropTypes.func
};
PresentationalCount.defaultProps = {
number: 0,
onIncrement: () => console.warn("onIncrement check")
};

export default PresentationalCount;

App.js에 presentationalCount.js추가

src/components/App.js

import React, { Component } from 'react';
import PresentationalCount from './PresentationalCount';

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

export default App;


드디어 Redux , 읽기전용인 redux에 action객체를 전달 하겠습니다.


actions 폴더에 두가지 파일 추가 합니다. 키워드는 상수생성자입니다.



ActionTypes.js는 액션 타입을 상수로 정의합니다. 

index.js에는 액션을 만드는 함수을 만들 것입니다.(생성자 생성)


ActionTypes.js에 더하기 기능을 추가하기위해 상수를 만듭니다.

src/actions/ActionTypes.js

export const INCREMENT = 'INCREMENT';

index.js에 action 생성자를 생성합니다.

index.js에서는 ActionTypes.js를 import 받습니다. 

src/actions/index.js

import * as types from './ActionTypes';

export const increment = () => ({
type: types.INCREMENT
});

export 형식으로 function을 만들고 type을 ActionTypes에서 받아온 상수를 설정합니다. 


다음은 reducers 폴더에 하나의 index.js 파일을 추가합니다.

src/reducers/index.js

import * as types from './ActionTypes';


// 액션 Type의 초기설정
const initialState = {
number: 0
};
// 리듀서 함수는 state와 action을 파라미터로 받습니다.
// state로 넘어오는 값이 없을 경우 initialState값이 사용됩니다.
function counter(state = initialState, action) {
switch (action.type) {
case types.INCREMENT:
return {
...state,
number: state.number + 1
};
default:
return state;
}
};


export default counter;

리듀서파일에서 액션 타입의 초기설정을 해줍니다. 

리듀서 함수는 action.type에 따라 작업이 되고, 새로운 상태를 반환하고 직접 state를 변경하면 안되고, 기존상태에 덮어쓴 새로운 상태를 반환해야합니다.

리듀서 함수는 항상 순수함수로 작성되어야합니다. 


store을 만들어서 reducer을 구독 하게 만듭니다. 

src/index.js

import React from 'react';
import ReactDOM from 'react-dom';
import App from './containers/App';
import './index.css';

// Redux 관련 불러오기
import { createStore } from 'redux'
import reducers from './reducers';
import { Provider } from 'react-redux';

// 스토어 생성
const store = createStore(reducers);

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

이제 contatiner 컴포넌트를 만들어서 store을 연결시켜 줍니다. 

store 연결을 react-redux의 connect로 합니다.


기존에 컴포넌트를 Presentaional 컴포넌트와 Container 컴포넌트를 나누어서 만들었습니다. 

반드시 해당 방법으로 만들어야하는것은 아니고, 하나의 아이디어입니다.


Presentational Component

 - VIew만 담당하는 컴포넌트

 - 주로 Props로 데이터를 받아옴

 - 주로 함수형

 - style 사용 

Container Component

 - Presentational component와 Container component 담당

 - Redux에 직접접근

 - class형

 - style 사용 안함, DOM Element는 감싸는 정도만사용

src/containers/CounterContainer.js

import PresentationalCount from '../components/PresentationalCount';
import * as actions from '../actions';
import { connect } from 'react-redux';

// store 안의 state 값을 props 로 연결해줍니다.
const mapStateToProps = (state) => ({
number: state.number
});

const mapDispatchToProps = (dispatch) => ({
onIncrement: () => dispatch(actions.increment())
});

// Counter 컴포넌트의 Container 컴포넌트
// Counter 컴포넌트를 어플리케이션의 데이터 레이어와 묶는 역할을 합니다.
const CounterContainer = connect(
mapStateToProps,
mapDispatchToProps
)(PresentationalCount);


export default CounterContainer;

마지막으로 App.js에서 만드신 container 컴포넌트를 설정해주시면됩니다.

src/containers/App.js

import React, { Component } from 'react';
import CounterContainer from './CounterContainer';

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

export default App;


이렇게 하시면 가장 간단한  Redux 프로젝트가 완성됩니다. 

다음 회차에는 조금더 난이도를 높여서 Redux를 한단계 한단계 진행해 보겠습니다.

진행 계획은 숫자 입력창을 만들어 직접 입력하는 Redux 프로젝트를 만들 계획입니다.



Redux 한글 : https://deminoth.github.io/redux/



'React > State Menagement' 카테고리의 다른 글

[ React ] LifeCycle API 리액트 생명주기 정리  (0) 2018.07.30
Comments