✅ redux / redux toolkit 설치
✅ store의 state 보관 및 사용
✅ store의 state 변경
✅ store의 state가 object,array일 경우
✅ redux를 활용하여 장바구니 만들기
redux setting
- react 18버전 이상일 것
- npm install @reduxjs/toolkit react-redux
- store.js 파일 만들기
import {configureStore} from '@reduxjs/toolkit'
- configureStore import하기
- index.js에 가서 부모요소로 Provider store={store}로 감싸기
import store from './store.js' <Provider store={store}> <App/> </Provider>
import { configureStore, createSlice } from "@reduxjs/toolkit";
let user = createSlice({
name : 'user',
initialState: 'kim',
})
export default configureStore ({
reducer : {
user : user.reducer,
}
})
redux로 state 만들기
- redux는 createSlice로 state를 생성할 수 있음
- name은 state의 이름을 뜻하고, initialStatesms state의 값을 나타냄
- state 하나를 slice라고 부름
- slice 생성을 했다면 configureStore에 등록을 해줄 수 있음.
- reducer 안에 작명 : user.reducer를 하면 등록 완료
redux로 state 끌어오기
import { useSelector } from "react-redux"; export default function Cart() { let state = useSelector((state) => { return state; }); console.log(state) // 결과값은 'user:kim'
- redux로 state 끌어오기 위해서는 useSelector를 imfort하고
- let 작명 = useSelector((state)=>{return state}) 하면 state가 작명된 변수에 저장이 됨.
- 이를 통해 props 없이 사용할 수 있음.
redux로 여러개의 state 중 원하는 state만 불러오기
let user = createSlice({ name : 'user', initialState: 'kim', }) let cart = createSlice({ name : 'cart', initialState: [10,11,12] export default configureStore ({ reducer : { user : user.reducer, cart : cart.reducer, } }) })
export default function Cart() { let state = useSelector((state) => { return state.cart; // cart state만 불러오기 가능 });
- 여러개의 state 중 원하는 state만 불러오고자 하면 .state이름 이런식으로 작성하면 된다.
redux 사용해서 장바구니 만들기
{state.cart.map((a, i) => { return ( <tr key={i}> <td>{state.cart[i].id}</td> <td>{state.cart[i].name}</td> <td>{state.cart[i].count}</td> <td> )
- map 함수 활용해서 해당 데이터들 끌어오면 됨.
reducers 함수로 state 값 변경하기
let user = createSlice({ name : 'user', initialState: 'kim', reducers : { changeName(state){ return 'john'+ state // john kim 출력 } export let { changeName, 함수 2, 함수 3 } = user.actions
- state안에 reducer로 함수를 만들어서 state의 값을 변경할 수 있음. 변경시에 함수의 인자로 아무거나 넘겨주면 기존 state 값을 불러올 수 있음.
- 함수를 import해서 밖에서도 사용할 수 있어야함. 위와 같이 user.actions를 import하면서 사용할 수 있음.
- 만든 함수 import 해서 사용 useDispatch()로 dispatch 먼저 선언해주고 사용해야함
import { useDispatch, useSelector } from "react-redux"; import { changeName } from "../store"; export default function Cart() { let state = useSelector((state) => { return state; }); let dispatch = useDispatch(); <button onClick={() => { dispatch(changeName()); }}
let user = createSlice({
name : 'user',
initialState: { name: 'kim', age:20},
reducers : {
changeName(state){
return state.name = 'park' // kim->park으로 변경, return 없이 직접 수정도 가능
},
increase(state,action) {
state.age += action.payload
},
increase(10)
increase(100)
파일 분할
- state를 한 곳에서 관리하면 너무 많으니까 분할해서 관리하는 것도 가능함
- 예를 들어, 이름 변경하는 Slice 따로 파일을 만들고 export 해주면 됨.
- 그리고 사용하고자 하는 곳에서 해당 변수(slice 할당된)를 불러오면 되는 것.
- store를 분할하고, 수정했을 경우 경로 수정 잘 해줄 것.
let cart = createSlice({
name : 'cart',
initialState: [
{id : 0, name : "White and Black", count:2},
{id : 2, name : "Grey Yordan", count:1},
],
reducers : {
changePlus(state, action) {
let number = state.findIndex((a)=>{return a.id === action.payload})
state[number].count++
}
}
})
>
<button
onClick={() => {
dispatch(changePlus(state.cart[i].id));
}}
>
장바구니 수량 추가하기
- 장바구니 수량을 추가할 때 해당 버튼에 있는 아이디를 찾아서 해당 id의 카운트를 늘려주는 방식으로 하면 에러가 안난다.
- findIndex 함수는 해당 배열의 index를 찾아주는 함수이다.