일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
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 |
Tags
- useQueryClient
- ?? #null병합연산자
- es6
- debouncing
- alias설정
- vite
- CustomHook
- accordian
- ㅡ
- ignore padding
- 문제해결
- Carousel
- tailwindCSS
- 조건부스타일
- twoarrow
- 화살표2개
- parent padding
- 부모패딩
- QueryClient
- 리액트
- 함수형프로그래밍
- transition
- 서초구보건소 #무료CPR교육
- createPortal
- BFC
- DOM
- react
- BlockFormattingContext
- 부모요소의 패딩 무시
- 제어컴포넌트
Archives
- Today
- Total
프론트엔드 첫걸음
[Redux Toolkit Tutorial] bindActionCreator 본문
Redux Toolkit Tutorial 9강
//import redux from 'redux';
const redux = require('redux');
const createStore = redux.createStore;
const bindActionCreators = redux.bindActionCreators;
const combineReducers = redux.combineReducers;
//상수를 만들어 놓으면 액션 재사용시 오타 방지할 수 있다.
//액션 정의
const CAKE_ORDERED = 'CAKE_ORDERED';
const CAKE_RESTOCKED = 'CAKE_RESTOCKED';
const ICECREAM_ORDERED = 'ICECREAM_ORDERED';
const ICECREAM_RESTOCKED = 'ICECREAM_RESTOCKED';
//액션을 반환하는 함수
function orderCake() {
return {
type: CAKE_ORDERED,
payload: 1,
// quantity: 1,
// 보내려는 추가정보에 대해 payload 속성을 사용하는 것이 리덕스 컨벤션
};
}
function restockCake(qty = 1) {
return {
type: CAKE_RESTOCKED,
payload: qty,
};
}
function orderIceCream(qty = 1) {
return {
type: ICECREAM_ORDERED,
payload: qty,
};
}
function restockIceCream(qty = 1) {
return {
type: ICECREAM_RESTOCKED,
payload: qty,
};
}
const initialCakeState = {
numOfCakes: 10,
};
const initialIceCreamState = {
numOfIceCreams: 20,
};
//reducer 를 하나의 관심사에 관한 reducer로 바꿈
const cakeReducer = (state = initialCakeState, action) => {
switch (action.type) {
case CAKE_ORDERED:
return {
...state,
numOfCakes: state.numOfCakes - 1,
};
case CAKE_RESTOCKED:
return {
...state,
numOfCakes: state.numOfCakes + action.payload,
};
default:
return state;
}
};
const iceCreamReducer = (state = initialIceCreamState, action) => {
switch (action.type) {
case ICECREAM_ORDERED:
return {
...state,
numOfIceCreams: state.numOfIceCreams - 1,
};
case ICECREAM_RESTOCKED:
return {
...state,
numOfIceCreams: state.numOfIceCreams + action.payload,
};
default:
return state;
}
};
const rootReducer = combineReducers({
cake: cakeReducer,
iceCream: iceCreamReducer,
});
const store = createStore(rootReducer);
console.log('initial State', store.getState());
//state바뀔때마다 log찍는 함수 실행
const unsubscribe = store.subscribe(() =>
console.log('update state', store.getState())
);
//orderCake()에서 return된 함수가 reducer로 dispatch됨
//함수로 반환하지 않으면 state가 수정된 경우 dispatch에 매개변수로 전달한 {type : CAKE_ORDERED}를 전부 수정해야함
// store.dispatch({
// type: CAKE_ORDERED,
// quantity: 1,
// });
// store.dispatch(orderCake());
// store.dispatch(orderCake());
// store.dispatch(orderCake());
// store.dispatch(restockCake(3));
const actions = bindActionCreators(
{ orderCake, restockCake, orderIceCream, restockIceCream },
store.dispatch
);
actions.orderCake();
actions.orderCake();
actions.orderCake();
actions.restockCake(3);
actions.orderIceCream();
actions.orderIceCream();
actions.restockIceCream(2);
unsubscribe();
//스토어의 변경사항을 구독취소했기 때문에 console에 기록되지 않음
store.dispatch(orderCake());
store.dispatch(orderCake());
Before
store.dispatch(orderCake());
store.dispatch(orderCake());
store.dispatch(orderCake());
store.dispatch(restockCake(3));
보통은 store 객체가 직접 dispatch를 호출한다.
After
bindActionCreator
- 액션생성함수들을 dispatch와 묶어주어 dispatch를 쉽게 한다.
값이 액션생성함수인 객체와 dispatch를 인수로 받아서 ,
액션생성함수를 호출할수 있는 bindActionCreator를 반환한다.
const bindActionCreators = redux.bindActionCreators;
const actions = bindActionCreators(
{
orderCake: orderCake,
restockCake: restockCake,
orderIceCream: orderIceCream,
restockIceCream: restockIceCream,
},
store.dispatch
);
actions.orderCake();
actions.orderCake();
actions.orderCake();
actions.restockCake(3);
actions.orderIceCream();
actions.orderIceCream();
actions.restockIceCream(2);
bindActionCreator로 dispatch를 포장하게 되면 react에서 하위 컴포넌트에 bindActionCreator를 넘겨줄 수 있는데,
이렇게 되면, 하위 컴포넌트에서 bindActionCreator를 import할 필요 없다.
bindActionCreator를 사용하지 않는다면 하위컴포넌트는 해당 store가 어떤 액션생성함수를 사용하는지 알아야한다.
(bindActionCreator로 사용하는 액션생성함수를 포장해서 넘겨주면 좀 더 사용이 용이할 것 같다.)
https://redux.js.org/api/bindactioncreators
예시
import React from 'react'
import { bindActionCreators } from 'redux'
import { connect } from 'react-redux'
import * as TodoActionCreators from './TodoActionCreators'
console.log(TodoActionCreators)
// {
// addTodo: Function, //액션생성자 함수
// removeTodo: Function
// }
function TodoListContainer(props) {
// Injected by react-redux:
const { dispatch, todos } = props
// Here's a good use case for bindActionCreators:
// You want a child component to be completely unaware of Redux.
// We create bound versions of these functions now so we can
// pass them down to our child later.
const boundActionCreators = useMemo(
() => bindActionCreators(TodoActionCreators, dispatch),
[dispatch]
)
console.log(boundActionCreators)
// {
// addTodo: Function,
// removeTodo: Function
// }
useEffect(() => {
// Note: this won't work:
// TodoActionCreators.addTodo('Use Redux')
// You're just calling a function that creates an action.
// You must dispatch the action, too!
// This will work:
let action = TodoActionCreators.addTodo('Use Redux')
dispatch(action)
}, [])
return <TodoList todos={todos} {...this.boundActionCreators} />
// An alternative to bindActionCreators is to pass
// just the dispatch function down, but then your child component
// needs to import action creators and know about them.
// return <TodoList todos={todos} dispatch={dispatch} />
}
export default connect(state => ({ todos: state.todos }))(TodoListContainer)
'개발 공부 > React' 카테고리의 다른 글
리덕스 관련 코드 작성하기 2. Hooks 사용하여 컨테이너 컴포넌트 만들기 (0) | 2022.09.06 |
---|---|
리덕스 관련 코드 작성하기 (0) | 2022.09.04 |
[Redux Toolkit Tutorial] Cake shop Scenario (0) | 2022.09.01 |
Redux Toolkit 이해하기 - vanila javascript에서 써보기 (0) | 2022.08.31 |
[문제해결] 중괄호와 괄호 헷갈리지 않게 잘 쓰기 (0) | 2022.08.30 |