헷갈려서 한번 정리함
let a = 10;
export default a;
export default 변수명
ㄴ 변수명은 자유롭게 작명 가능
let a = 10;
let b = 100;
// export default a, b; < 이렇게 안됨,,
export { a, b } ;
export { 변수명, 변수명2 }
ㄴ 참고: import 도 모양에 맞춰서 {변수, 변수}
import data from "./data.js";
import 변수이름 from '경로'
참고: .js 확장자는 생략 가능
import {a, b} from "./data.js";
import { 변수이름, 변수이름2 } from '경로'
주의 : 중괄호로 여러개 import 할 때는 자유롭게 작명이 안됨!
export 했던 변수명 그대로 사용해야 한다.
actions 를 잘못 export하는 바람에 에러가 났다.
(0 , _store_userSlice_js__WEBPACK_IMPORTED_MODULE_0__.increaseCount) is not a function
store.js
import { configureStore, createSlice } from "@reduxjs/toolkit";
import { user, cart } from "./store/userSlice.js";
let stock = createSlice({
name: "stock",
initialState: [10, 11, 12],
});
export default configureStore({
reducer: {
user: user.reducer,
stock: stock.reducer,
cart: cart.reducer,
},
});
userSlice.js
import { createSlice } from "@reduxjs/toolkit";
let cart = createSlice({
name: "cart",
initialState: [
{ id: 0, name: "White and Black", count: 2 },
{ id: 2, name: "Grey Yordan", count: 1 },
],
reducers: {
increaseCount(state, action) {
// 파라미터는 보통 action이라고 작명한다
let idx = state.findIndex((item) => item.id === action.payload);
if (idx !== -1) {
// jsx에서는 !==, === 을 권장함 (데이터 타입까지 일치)
state[idx].count++;
}
},
}
});
let user = createSlice({
name: "user", // state 이름
initialState: { name: "kim", age: 20 }, //state 값
reducers: {
changeName(state, i) {
},
changeAge(state, a) {
state.age += a.payload;
},
},
});
export {user, cart};
export let { changeName, changeAge, increaseCount } = user.actions;
Cart.js
import { Table } from "react-bootstrap";
import { useSelector, useDispatch } from "react-redux";
import { changeName, changeAge, increaseCount } from "../store/userSlice.js";
function Cart() {
let state = useSelector((state) => {
return state;
});
let dispatch = useDispatch();
let cart = useSelector((state) => state.cart);
return (
(중략)
<thead>
<tr>
<th>#</th>
<th>상품명</th>
<th>수량</th>
<th>변경하기</th>
</tr>
</thead>
<tbody>
{cart.map((item, i) => {
return (
<tr key={i}>
<td>{item.id}</td>
<td>{item.name}</td>
<td>{item.count}</td>
<td>
<button
onClick={() => {
dispatch(increaseCount(item.id));
/* 클릭하면 이 id 번째의 수량을 1 증가시킨다 */
}}
>
{" "}
+{" "}
</button>
</td>
</tr>
);
})}
</tbody>
에러의 원인은 increaseCount 액션을 userSlice.js에서 user.actions로부터 가져오고 있기 때문입니다. 하지만 increaseCount는 cart 슬라이스의 액션이지 user 슬라이스의 액션이 아닙니다.
increaseCount 액션을 올바르게 cart.actions에서 추출해야 합니다.
actions는 슬라이스별로 따로였던 거임...!!!!
원래 user에 넣어놨다가 이거 cart에 넣어야겠는데?하고 cart로 옮기는 와중에 뭔가 빼먹었나 싶었는데 저거였다
네, 맞습니다! 🎯
Redux Toolkit에서 createSlice를 사용하면, 각 Slice마다 별도의 actions 객체가 생성됩니다.
actions 객체란?createSlice를 사용하면 자동으로 reducers 객체에 정의된 함수들에 대한 액션 생성자(action creator)를 포함하는 actions 객체가 만들어집니다.
즉, createSlice를 호출할 때마다:
1. reducers에 정의된 함수들에 대해 액션 생성자가 자동 생성됨.
2. 해당 액션 생성자들은 slice.actions에 객체 형태로 저장됨.
3. 따라서, actions 객체는 각 Slice마다 개별적으로 존재함.
아래처럼 user와 cart라는 두 개의 Slice가 있을 때:
import { createSlice } from "@reduxjs/toolkit";
let user = createSlice({
name: "user",
initialState: { name: "kim", age: 20 },
reducers: {
changeName(state) {
state.name = "park";
},
changeAge(state, action) {
state.age += action.payload;
},
},
});
let cart = createSlice({
name: "cart",
initialState: [{ id: 0, name: "Shoes", count: 1 }],
reducers: {
increaseCount(state, action) {
let idx = state.findIndex((item) => item.id === action.payload);
if (idx !== -1) {
state[idx].count++;
}
},
},
});
actions 객체가 개별적으로 존재!user.actions{
changeName: function,
changeAge: function
}cart.actions{
increaseCount: function
}actions를 올바르게 가져오는 방법👉 각 Slice에서 개별적으로 actions를 가져와야 합니다.
export let { changeName, changeAge } = user.actions; // user의 actions
export let { increaseCount } = cart.actions; // cart의 actions
이렇게 하면 changeName과 changeAge는 user의 액션,
increaseCount는 cart의 액션으로 가져오게 됩니다.
actions 객체는 각 Slice마다 별도로 생성됨.actions를 가져올 때, 반드시 각 Slice에서 따로 가져와야 함.user.actions에는 user 관련 액션만, cart.actions에는 cart 관련 액션만 있음.