본문 바로가기
풀스택/React

7-2 카운터 예제(redux)

by woohyun22 2019. 4. 24.

Redux를 사용하기에, store를 사용하게된다. dispatch가 호출되고 state가 업데이트되고, subscribe가 호출되면, 데이터 변동이 있을때마다 리랜더링이 되도록 설정


- dispatch =  store 업데이트

- subscribe = 데이터 변환됫것 적용


먼저 

npm install --save redux

redux모듈을 설치하고 진행


src/actions/index.js

export const INCREMENT = 'INCREMENT';//action의 type을 정의하여 export
export const DECREMENT = 'DECREMENT';
export const SET_DIFF = 'SET_DIFF';

export function increment() {//함수들을 정의
return {
type: INCREMENT
};
}

export function decrement() {
return {
type: DECREMENT
};
}

export function setDiff(value) {//더하고 뺼값을 diff에 저장
return {
type: SET_DIFF,
diff: value
};
}


action은 어떤 변화가 일어나야 할지 알려주는 객체이다.

작성할때, 첫번째 필드 type은 필수적으로 포함되야한다.  id개념으로 쓰임.


src/reducers/index.js

import { INCREMENT, DECREMENT, SET_DIFF } from '../actions';//action의 type들 import
import { combineReducers } from 'redux';

const counterInitialState = {//state 초기값 정의
value: 0,
diff: 1
};

const counter = (state = counterInitialState, action) => {
//default parameter을 이용해 state가 undefined로 들어올경우 state값을 초기값으로 설정
switch(action.type) {
case INCREMENT:
return Object.assign({}, state, {
//state를 변경시키지 않고 Object.assign 메소드를 통해 state를 복사, 그 객체를 수정하여 리턴한다.
value: state.value + state.diff
});
case DECREMENT:
return Object.assign({}, state, {
value: state.value - state.diff
});
case SET_DIFF:
return Object.assign({}, state, {
diff: action.diff
});
default:
return state;
}
}

const counterApp = combineReducers({//reducer를 하나로 합쳐줌
counter
});

export default counterApp;


src/components/Counter.js


import React, { Component } from 'react';

class Counter extends Component {
render() {
return (
<div>
<h1>Value : {this.props.store.getState().counter.value}</h1>
</div>
);
}
}

export default Counter;


store.getState()로 store에 저장된 state를 가져와서, count.value 출력


src/components/Option.js

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

class Option extends Component {
constructor(props) {
super(props);

this.onChange = this.onChange.bind(this);
}

onChange(event) {
this.props.store.dispatch(setDiff(parseInt(event.target.value)));
//dispatch는 reducer로 action을 전달, reducer은 store에 state를 저장
}

render() {
return (
<div>
<input value={this.props.store.getState().counter.diff} onChange={this.onChange} />
</div>
);
}
}

export default Option;


store.getState()로 state를 가져와 counter.diff 출력


src/components/Button.js

import React, { Component } from 'react';
import { increment, decrement } from '../actions';

class Button extends Component {
constructor(props) {
super(props);

this.onIncrement = this.onIncrement.bind(this);
this.onDecrement = this.onDecrement.bind(this);
}

onIncrement(event) {
this.props.store.dispatch(increment())
}

onDecrement(event) {
this.props.store.dispatch(decrement())
}

render() {
return (
<div>
<button onClick={this.onIncrement}>+</button>
<button onClick={this.onDecrement}>-</button>
</div>
);
}
}

export default Button;


dispatch 처리


App.js

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

import Counter from './components/Counter';
import Option from './components/Option';
import Button from './components/Button';

class App extends Component {
render() {
return (
<div>
<Counter store={this.props.store} />
<Option store={this.props.store} />
<Button store={this.props.store} />
</div>
);
}
}

export default App;


store import 및 컴포넌트에 store 전달



728x90

'풀스택 > React' 카테고리의 다른 글

8-1 react 프로젝트(react eclipse 연동)  (0) 2019.05.09
리액트 오류 하나씩 추가하기  (0) 2019.05.03
7-1 카운터 예제(react)  (0) 2019.04.24
6. input  (0) 2019.04.23
5-2. props, state  (0) 2019.04.21

댓글