장바구니에 상품 추가 기능을 구현할 때 상품목록을 state로 관리해야한다면 상품목록은 store에 저장한 후 상태 변경이 필요할 때는 reducer를 통해 변경해준다. actions의 payload에 추가할 상품의 정보를 담아 dispatch를 통해 reducer의 인자로 보내준다.
상태를 변경이 필요한 이벤트 발생 시 실행해 줄 actions 생성자 함수를 만든다.
action 생성자 함수란 reducer함수가 인자로 받을 action객체를 생성하는 함수이다.
action객체는 type와 reducer에 전달해줄 내용이 들어 있는 payload로 구성되었다.
그러므로 상태변경 시 필요할 인자들을 payload로 전달해야한다.
export const 추가하기action생성자함수 = (itemId) => {
return {
type: 'ADD_TO_CART',
payload: {
itemId,
quantity: 1
}
}
}
type을 export const ADD_TO_CART = "ADD_TO_CART";
과 같이 변수에 담아주면 type: 'ADD_TO_CART' 대시 type: ADD_TO_CART으로 작성할 수 있다.
actions 생성자 함수를 실행할 때는 dispatch함수의 콜백함수로 실해시켜줘야 reducer로 actions가 전달된다.
const dispatch = useDispatch();
const handleClick = (item) => {dispatch(추가하기action생성자함수(item.id))}
actions을 인자로 실행할 Reducer 함수를 만들어준다.
Reducer 함수는 인자로 받는 action의 type에 따라 상태를 변경해준다. 변경시 기존을 상태를 복사한 후 바꿀 부분만 변경해 상태의 전체를 다시 리턴해줘야한다.
Reducer = (state = 상태의 초기값, action) => {type에 따라 리턴할 변경된 상태} 형식으로 작성한다.
const 추가하기Reducer = (state = 상태의 초기값, action) => {
switch (action.type) {
case 'ADD_TO_CART': // action.type
// 원본 state는 복사 한 후 수정부분 덮어씌워 리턴
return Object.assign({}, state, {
cartItems: [...state.cartItems, action.payload]
})
default:
return state; // 타입이 없다면 원래 state 반환
}
}
만든 reducer함수를 store에 전해 줘야한다.
createStore
을 import한 후 createStore
로 상태를 저장해둘 store을 만든다.createStore
에 인자로 Reducer 함수를 전달해주어야한다.import { createStore } from 'redux';
const store = createStore(추가하기reducer);
Provider
로 APP 컴포넌트 감싸 전역 상태 저장소 store을 props로 전달해 준다. root.render(
<Provider store={store}>
<App />
</Provider>
);
useSelector라는 hook을 사용한다. useSelector를 사용하면 state를 불러올 수 있다.
import { useSelector } from 'react-redux'
const counter = useSelector(state => state) // counter에 state 전체가 저장됨
Object.assign()은 여러개의 객체를 병합시켜주는데, 첫번째 인자로 받은 객체으로 병합 시켜준다. 그래서 앞에 첫번째 인자로 {}을 넣어주면 복사본을 만들 수 있다.
또한 객체를 병합할 때 겹치는 키가 있다면 그 키의 값은 뒤쪽에 들어온 객체를 기준으로 합쳐준다.
const target = { a: 1, b: 2 };
const source = { b: 4, c: 5 };
const returnedTarget = Object.assign(target, source);
console.log(target); // { a: 1, b: 4, c: 5 }
console.log(returnedTarget === target); // true(주소값같다)
const copy = Object.assign({}, target)
console.log(copy) // { a: 1, b: 2 }
console.log(copy === target) // false
스프레드 문법도 assign과 같이 뒤에 오는 객체를 기준으로 덮어씌워준다.
const target = { a: 1, b: 2 };
const source = { b: 4, c: 5 };
console.log({...target, ...source}) // {a: 1, b: 4, c: 5}
redux-thunk는 리덕스에서 비동기 작업을 처리 할 때 가장 많이 사용하는 미들웨어입니다. 이 미들웨어를 사용하면 액션 객체가 아닌 함수를 디스패치 할 수 있습니다.
상품 수량변경 함수작성할 때 인자 순서 바뀐줄 모르고 작성했다가 이부분 찾아서 고치는데 시간을 많이 썼다... 함수 인자 순서의 중요성을 크게 느꼈다. 리덕스 뭔가 이해될 듯하면서도 파일은 전체적으로 이동하면서 작성하다보니깐 헷가리는 부분도 많은 것 같다.