npm install @reduxjs/toolkit react-redux
createSlice()
로 state를 생성createSlice()
의 reducer
에 state변경 함수(action) 생성configureStore()
선언 후 reducer
에 통해 state등록 후 exportuseSelector()
한 파일에서는 해당 state를 언제/어디서든 사용/변경 가능export let { export할 action들 여러 개 등록 가능 } = state명.actions
useSelector()
와 useDispatch()
를 이용하여 state 사용let state = useSelector((state)=>{ return state })
let dispatch = useDispatch()
dispatch(action명(state.state명))
Redux는 React와 같이 라이브러리이기 때문에 설치해서 사용해야 함
npm install @reduxjs/toolkit react-redux
입력 "react": "^18.1.0",
"react-dom": "^18.1.0", ...
<BrowswerRouter>
컴포넌트를 <Provider>
컴포넌트로 감싸기<BrowswerRouter>
없으면 <App>
컴포넌트 감싸기) /* index.js */
import {Provider} from 'react-redux'; //Provier컴포넌트 import 필요
import store from './store.js'; //store.js 파일 만들어놓고 import
<Provider store={store}>
<BroswerRouter>
<App />
</BroswerRouter>
</Provider>
/* store.js : state들 생성 및 등록 */
import {configureStore, createSlice} from '@reduxjs/toolkit';
//state생성
let state명 = createSlice({
name : 'state명',
initialState : 'state값'
})
//state등록
export default configureStore({
reducer: {
//이곳에 등록할 state들 모두 입력
state명 : state명.reducer
}
})
/* state사용할 컴포넌트가 있는 파일 */
import {useSelector} from "react-redux";
function 컴포넌트명(){
let state사용할이름 = useSelector((state)=>{ return state })
//let state사용할이름 = useSelector((state) => state) : 위와 같은 문법
//let state사용할이름 = useSelector((state) => state.특정state명)
// : store에서 특정 state만 꺼내서 'state사용할이름' 에 저장
return(
console.log(state사용할이름) //store에 저장되어있는 state 모두 출력
console.log(state사용할이름.특정state명) //특정 state만 출력
)
}
/* store.js : state/action 생성 및 등록 */
import {configureStore, createSlice} from '@reduxjs/toolkit';
let state명 = createSlice({
name : 'state명',
initialState : 'state값',
reducers : {
//이곳에 현재 state와 관련된 모든 변경 함수(action) 생성
action명(state, action){
//state : 주로 state라고 작명, 해당 state 자체를 가리킴 (객체 느낌)
//action : 주로 action이라고 작명, 일반 함수에서의 파라미터 역할을 담당
//이곳에 state를 변경할 코드 작성
state.name = '변경할 state이름' //이런식으로 사용
state.name = action.payload //action을 사용한 예시
//action사용 시 무조건 .payload를 붙임
},
action2명(state, action){
//이렇게 action은 여러 개 선언 가능 (setState보다 더 세세한 기능 구현 가능)
}
}
})
import { useDispatch, useSelector } from "react-redux";
import { 사용할 action명 } from "../store.js";
function 사용할컴포넌트(){
(중략)
let state = useSelector((state)=>{ return state }) // state 가져오기
let dispatch = useDispatch() //주로 dispatch로 작명한 변수에 저장해서 사용
//dispatch()를 통해 action를 호출
dispatch(action명(파라미터))
//파라미터는 위에서 생성한 action의 "action"변수를 뜻함
//"state" 파라미터는 넘기지 않음
}
👉🏻 컴포넌트에서 직접 setState()
로 변경하는 것이 아니라, store.js에 저장되어 있는
action을 직접 호출함으로써 사용!
== 문제가 생기면 store.js에 저장된 action함수만 고치면 된다는 뜻!
/* stroe.js */
import {configureStore, createSlice} from '@reduxjs/toolkit';
//state생성
let cart = createSlice({
name : 'cart',
initialState : [
{id : 0, name : '첫번째상품', count : 2},
{id : 2, name : '두번째상품', count : 1}
],
//state가 리스트 형식이면 initialState(값저장)에 리스트 그대로 저장!
//action생성 (count 증가 함수)
reducer : {
addCount(state, action){
let index = state.findIndex((x)=> x.id == action.payload )
//❓findIndex쓰는이유 : 아래 참고
state[index].count++
}
}
})
//cart를 사용하는 파일에 addCount() action export
export let { addCount } = cart.actions
//state 등록 및 export
export default configureStore({
reducer: {
cart : cart.reducer //다른 곳에서 cart로 사용함
}
})
👉🏻 createSlice()
로 state를 생성하고, configureStore()
의 reducer
를 통해 state등록
: 정렬 등으로 인해 state 값이 변경될 경우, 정렬된 데이터의 id값이 아닌 state에 저장되어 있는
고유의 id값을 가진 index를 찾기 위함
/* Cart.js */
import {useSelector} from "react-redux";
function Cart(){
//state라는 변수에 store 저장
let state = useSelector((state) => { return state })
//map을 이용하여 리스트 자료 개수만큼 출력하기
return(
{
state.cart.map((a,i)=>{
return(
<tbody>
<tr>
<td>{(i+1)}</td>
//state 사용하기 (출력)
<td>{state.cart[i].name}</td>
<td>{state.cart[i].count}</td>
//action 사용하기 (변경 : 버튼 클릭 시 count값 증가)
<td>
<button onClick={()=>{ dispatch(addCount(state.cart[i].id)) }}>+</button>
</td>
</tr>
</tbody>
)
})
}
)
}
👉🏻 useSelector()
를 통해 변수에 store를 저장하고, 변수.state명
state 출력
👉🏻 map 사용법은 내 포스팅 : [React] Map(data,i) ← 여기서 확인!
👉🏻 useDispatch()
를 통해 변수에 action을 저장하고, dispatch(action명(파라미터))
으로 사용
useSelector(), configureStore(), createSlice()
등 다양한 세팅이 필요함useDispatch()
를 저장한 변수로 호출해야 함