State
와 정의한 Action Type
으로 Reducer함수
를 만들면 된다.
이때 Reducer는 꼭 순수 함수로 만들어야 한다.
아래 4가지 조건을 만족하면 된다.
function counter(state = initialState, action) {
switch (action.type) {
case INCREASE :
return {
number: state.number +1
};
case DECREASE :
return {
number: state.number -1
};
default :
return state;
}
}
export default counter;
Action type에 따라 state를 변형한 새로운 state를 반환
해주면 된다.
절대로 기존 state
를 수정해서는 안됨.
createAction메소드를 사용해 action타입을 반환하는 함수를 만들어준다.
export const increase = createAction(INCREASE);
export const decrease = createAction(DECREASE);
//만약 파라미터를 전달해줘야 한다면 payload를 사용하면 됨.
export const changeInput = createAction(CHANGE_INPUT, input => input);
코드가 길어질때
redux-actions
라이브러리를 사용해 switch-case에서 벗어 날 수 있다.
const counter = handleActions (
{
[INCREASE] : (state,action) => (
{
number:state.number +1
}
),
[DECREASE] : (state,action)=>(
{
number: state.number -1
}
),
initialState
}
);
createAction에서 payload를 넣어줬다면?
const counter = handleActions (
{
[INCREASE] : (state,action) => (
{
number:state.number +1
}
),
[DECREASE] : (state,action)=>(
{
number: state.number -1
}
),
[CHANGE_INPUT] : (state,action) => (
{
...state,
input : action.payload
}
)
initialState
}
);
위와 같이 작성하면 payload에 어떤 값을 넣었는지 헷갈리므로
handleActions (
{
[CHANGE_INPUT] : (state,{payload:input})=>(
{
...state,
input: input
}
)
},
initialState
);
이런식으로 작성하면 가독성이 좋아진다.
ReduxStore에는 하나의 Reducer만 연결되어야 하므로 reducer를 통합해야한다.
redux는 combineReducers
라는 함수를 사용한다.
import {combineReducers} from 'redux';
import counter from './counter';
const rootReducer = combineReducers({
counter
});
export default rootReducer;
combineReducers메소드 안에 객체 형태로 우리가 만든 Reducer를 넣어주면 됨.
const rootReducer = combineReducers ({
counter1,
counter2,
counter3
});
useSelector
를 이용하면 connect
함수 없이 redux를 조회할 수 있다.
const result = useSelector(상태 선택 함수);
import {useSelector} from 'react-redux';
const CounterContainer = ()=>{
const counterNum = useSelector(state=> state.counter.number)
return (
<Counter number = {counterNume}/>
);
};
const dispatch = useDispatch();
를 이용해 dispatch를 얻은 후에 modules에서 얻은 함수를 넣어준다.
import {useSelector} from 'react-redux';
const CounterContainer = ()=>{
const counterNum = useSelector(state=> state.counter.number);
const dispatch = useDispatch();
return (
<Counter
number = {counterNume}
onIncrease = {()=>dispatch(increase())}
onDecrease = {()}
/>
);
};
이렇게 작성하면 숫자가 바뀔때마다 컴포넌트가 리렌더링 됨
-> 매번 함수를 새로 만드므로 useCallback으로 감싸준다.
import React, {useCallback} from 'react';
const CounterContainer = () => {
const CounterNum = useSelector(state=>state.counter.number);
const dispatch = useDispatch();
const onIncrease = useCallback(()=>dispatch(increase(),[dispatch]));
const onDecrease = useCallback(()=>dispatch(decrease(),[dispatch]));
return (
<Counter
number = {counterNum}
onIncrese = {onIncrease}
onDerease = {onDecrease}
/>
);
};