React
Redux Store 상태 값 변경하기
뮹뭉묵목몽묭
2019. 9. 20. 18:51
저번 게시글과 이어서 얘기해 보자면
https://whydoihavetousehypon-0.tistory.com/44
Redux와 React 연결하기
Redux 자체로는 엄연히 독립적인 library이기 때문에 자동으로 React에게 연결이 된다거나 아니면 React에게 연결되는 기능이 있다거나 하지는 않는다. React-Redux라는 library를 이용해야 React가 Redux를 통해..
whydoihavetousehypon-0.tistory.com
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
|
import React, { Component } from 'react';
import CounterControl from '../../components/CounterControl/CounterControl';
import CounterOutput from '../../components/CounterOutput/CounterOutput';
import {connect} from 'react-redux';
class Counter extends Component {
state = {
counter: 0
}
counterChangedHandler = ( action, value ) => {
switch ( action ) {
case 'inc':
this.setState( ( prevState ) => { return { counter: prevState.counter + 1 } } )
break;
case 'dec':
this.setState( ( prevState ) => { return { counter: prevState.counter - 1 } } )
break;
case 'add':
this.setState( ( prevState ) => { return { counter: prevState.counter + value } } )
break;
case 'sub':
this.setState( ( prevState ) => { return { counter: prevState.counter - value } } )
break;
}
}
render () {
return (
<div>
{/* 더이상 this.state.counter 을 사용할 필요가 없어졌다. */}
<CounterOutput value={this.props.ctr} />
{/* 밑에서 정의한 onIncrementCounter가 클릭될때마다 실행될수 있도록 지정해준다 */}
<CounterControl label="Increment" clicked={this.props.onIncrementCounter} />
<CounterControl label="Decrement" clicked={() => this.counterChangedHandler( 'dec' )} />
<CounterControl label="Add 5" clicked={() => this.counterChangedHandler( 'add', 5 )} />
<CounterControl label="Subtract 5" clicked={() => this.counterChangedHandler( 'sub', 5 )} />
</div>
);
}
}
// StatetoProps라는 함수를 정의 한다. 이 함수는 Store로 부터 상태를 받오는 함수이다.
// store로 부터 상태를 매개변수로 받는다.
const mapStateToProps = state => {
return {
// 상태의 counter값이 ctr이라는 키의 값으로 저장된 상태.
ctr:state.counter
};
};
//dispatch 함수를 받아 함수 객체를 return 하는 함수를 정의한다.
const mapDispatchToProps = dispatch => {
return {
//onInncrementCounter 불러지면 "INCREMENT"타입의 action을 매개변수로 가지고 있는
//dispatch함수가 불러진다.
onIncrementCounter:() => dispatch({type: 'INCREMENT'})
};
};
//connect는 위 함수(mapStateToProps) 이용해서 상태에서 counter값을 props의 형태로 전달한다.
//mapDispatchtoProps또한 connect에 포함시켜준다.
export default connect(mapStateToProps, mapDispatchToProps) (Counter);
|
cs |
counter.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
|
const initialState = {
counter:0
};
//Reducer
const reducer = (state=initialState, action) => {
//type에 따른 논리들을 정의해준다.
//INCREMENT 타입은 상태의 값을 1씩 증가시킨다.
if(action.type==="INCREMENT") {
return{
counter:state.counter+1
}
}
return state;
}
export default reducer;
|
cs |
store.js
저번에는 dispatch를 props로 받아오지 못해서 상태의 값들을 변경할수가 없었지만 dispatch를 받아오는 함수를 구현하고 해당 action type에 따라 reducer에 논리를 구현해 주니 상태의 값이 변경되는것을 확인할수가 있다.
하지만 현재는 increment 버튼만 작동이 되고 있다. 다른 버튼들도 작동 하도록 구현해보자.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
|
import React, { Component } from 'react';
import CounterControl from '../../components/CounterControl/CounterControl';
import CounterOutput from '../../components/CounterOutput/CounterOutput';
import {connect} from 'react-redux';
class Counter extends Component {
state = {
counter: 0
}
counterChangedHandler = ( action, value ) => {
switch ( action ) {
case 'inc':
this.setState( ( prevState ) => { return { counter: prevState.counter + 1 } } )
break;
case 'dec':
this.setState( ( prevState ) => { return { counter: prevState.counter - 1 } } )
break;
case 'add':
this.setState( ( prevState ) => { return { counter: prevState.counter + value } } )
break;
case 'sub':
this.setState( ( prevState ) => { return { counter: prevState.counter - value } } )
break;
}
}
render () {
return (
<div>
{/* 더이상 this.state.counter 을 사용할 필요가 없어졌다. */}
<CounterOutput value={this.props.ctr} />
{/* 밑에서 정의한 onIncrementCounter가 클릭될때마다 실행될수 있도록 지정해준다 */}
<CounterControl label="Increment" clicked={this.props.onIncrementCounter} />
<CounterControl label="Decrement" clicked={this.props.onDecrementCounter} />
<CounterControl label="Add 5" clicked={this.props.onAddCounter} />
<CounterControl label="Subtract 5" clicked={this.props.onSubCounter} />
</div>
);
}
}
// StatetoProps라는 함수를 정의 한다. 이 함수는 Store로 부터 상태를 받오는 함수이다.
// store로 부터 상태를 매개변수로 받는다.
const mapStateToProps = state => {
return {
// 상태의 counter값이 ctr이라는 키의 값으로 저장된 상태.
ctr:state.counter
};
};
//dispatch 함수를 받아 함수 객체를 return 하는 함수를 정의한다.
const mapDispatchToProps = dispatch => {
return {
//onInncrementCounter 불러지면 "INCREMENT"타입의 action을 매개변수로 가지고 있는
//dispatch함수가 불러진다.
onIncrementCounter:() => dispatch({type: 'INCREMENT'}),
//1씩 감소 시키는 함수
onDecrementCounter:() => dispatch({type:"DECREMENT"}),
//5씩 증가 시키는 함수
onAddCounter:() => dispatch({type:"ADD", value:5}),
//5씩 감소 시키는 함수
onSubCounter:() => dispatch({type:"SUBTRACT", value:5})
};
};
//connect는 위 함수(mapStateToProps) 이용해서 상태에서 counter값을 props의 형태로 전달한다.
//mapDispatchtoProps또한 connect에 포함시켜준다.
export default connect(mapStateToProps, mapDispatchToProps) (Counter);
|
cs |
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
|
const initialState = {
counter:0
};
//Reducer
const reducer = (state=initialState, action) => {
//type에 따른 논리들을 정의해준다.
//action type이 여러개로 늘은 경우 switch로 관리하면 코딩하기가 편하다.
switch(action.type) {
//INCREMENT 타입은 상태의 값을 1씩 증가시킨다.
case "INCREMENT" :
return { counter:state.counter+1}
//1씩 감소
case "DECREMENT" :
return {counter:state.counter-1}
//action value 만큼 증가
case "ADD" :
return {counter:state.counter+action.value}
//action value 만큼 감소
case "SUBTRACT" :
return {counter:state.counter-action.value}
default :
return state;
}
}
export default reducer;
|
cs |
위와 같이 앱의 Add 5을 포함한 모든 버튼이 잘 작동한다.