Redux란?
props 없이 state를 공유할 수 있도록 도와주는 라이브러리다.
하나의 js 파일에 state를 보관하고, 모든 컴포넌트들이 state를 직접 꺼내쓸 수 있다.
Redux 설치
npm install @reduxjs/toolkit react-redux
터미널에 위 명령어를 실행시킨다.
주의사항
package.json 파일에서 react와 react-dom이 18.1.0 버전 이상이어야 문제없이 설치가 가능하다.
만약 보다 낮으면, 직접 파일 수정하면 된다.
Redux 파일 생성
import { configureStore } from "@reduxjs/toolkit";
export default configureStore({
reducer: {
}
})
state를 보관할 js 파일을 만들고 위 코드를 입력한다.(난 store.js 라고 명명했다.)
index.js 파일 수정
import { Provider } from 'react-redux';
import store from './sotre.js'
const root = ReactDOM.createRoot(document.getElementById('root'));
root.render(
// 이제 stre.js에 있던 스테이트를 모든 컴포넌트들이 꺼내 쓸 수 있음
<Provider store={store}>
<BrowserRouter>
<App />
</BrowserRouter>
</Provider>
);
아까 작성한 Redux 파일을 import한다.
그리고 Provider 태그로 BrowserRouter를 감싸준 뒤,store 속성에 방금 import했던 파일을 넣어주면
앞으로 해당 파일에 있는 state들을 App과 모든 자식 컴포넌트들이 state를 꺼내쓸 수 있게 된다.
Redux 파일에 state 보관하기
import { configureStore, createSlice } from "@reduxjs/toolkit";
//useState랑 비슷한 용도, state하나를 slice라고 부름
let user = createSlice({
name : 'user', // state이름
initialState : 'kim' // state 값
})
let stock = createSlice({
name : 'stock',
initialState : [10,11,12]
})
export default configureStore({
reducer: {
userInfo : user.reducer,
stock : stock.reducer
}
})
createSlice를 통해 state를 Redux 파일에 보관한다.
name은 state 이름, initialState는 값을 의미한다.
export 문에 reducer에서 createSlice를 통해
작명할 이름 : state이름.reducer 를 입력하면 모든 컴포넌트에서 state 사용이 가능해진다.
컴포넌트에서 Redux 사용법
import { useSelector } from 'react-redux';
function Cart(){
// (state)는 Redux파일에 있던 모든 state를 뜻하며, 가져올 때 이처럼 사용
let a = useSelector((state)=>{return state})
console.log(a)
return (
<div>
</div>
)
}
export default Cart
useSelector를 통해 Redux에 등록해둔 state를 가져다 쓸 수 있다.
a.userInfo, a.stock과 같은 방식으로 특정 state 값을 가져올 수도 있으며,
useSelector에서 state.userInfo, state.stock과 같은 방법을 사용하여 특정 state값을 가져올 수도 있다.
Redux에 저장한 state 변경하는 법
import { configureStore, createSlice } from "@reduxjs/toolkit";
//useState랑 비슷한 용도, state하나를 slice라고 부름
let user = createSlice({
name : 'user', // state이름
initialState : 'kim', // state 값
reducers : {
changeName(state){
return 'park'
},
changeName2(state){
return 'Lee'
}
}
})
// 등호 오른쪽 자료에서 export할 자료 보냄
export let {changeName,changeName2} = user.actions
export default configureStore({
reducer: {
userInfo : user.reducer
}
})
reducers 에 state 변경 함수를 작성할 수 있다.
위처럼 해당 state 상태값이 kim이었던 것을 park 또는 Lee로 변경할 수 있는 함수를 작성했다.
export를 통해 다른 컴포넌트들이 사용할 수 있도록 해줘야한다.
그 다음 컴포넌트에서는 해당 함수를 사용할 수 있도록 import하고
dispatch 함수를 통해 Redux 파일 내부에 있는 함수에 접근하여 state 값을 변경하도록 한다.
import { useDispatch, useSelector } from 'react-redux';
import { changeName, changeName2 } from './../store';
function Cart(){
// (state)는 Redux파일에 있던 모든 state를 뜻하며, 가져올 때 이처럼 사용
let a = useSelector((state)=>{return state})
const dispatch = useDispatch(); // useDispatch를 통해 dispatch 함수를 가져옴
console.log(a)
return (
<div>
{a.userInfo}의 장바구니
<button onClick={()=>{
dispatch(changeName())
}}>+</button>
</div>
)
}
export default Cart
dispatch 함수를 통해 Redux 파일에 접근하도록 하는 이유는
잘못된 state값 변경이 발생했을 경우 빠른 오류 수정을 하기 위해서다.
만약 dispatch를 통해 Redux 파일 내부에서 state값을 변경하지 않고
각기 다른 컴포넌트에서 state 값을 변경했을 경우, 어떤 컴포넌트에서 잘못된 수정을 했는지 파악하기 어렵다.
따라서 dispatch를 통해 Redux 파일 내부의 state 변경 함수를 쓰는 것이 바람직하다.
state가 object/array일 경우 변경하는 방법
import { configureStore, createSlice } from "@reduxjs/toolkit";
//useState랑 비슷한 용도, state하나를 slice라고 부름
let user = createSlice({
name : 'user', // state이름
initialState : { name :'kim', age : 20}, // state 값
reducers : {
changeName(state){
return { name :'park', age : 20}
},
changeName2(state){
state.name = 'park'
}
changeName3(state,action){ // dispatch(changeName3(100)) 하면 100씩 늘어남
state.age+=action.payload
}
}
})
// 등호 오른쪽 자료에서 export할 자료 보냄
export let {changeName,changeName2, changeName3} = user.actions
export default configureStore({
reducer: {
userInfo : user.reducer
}
})
array 및 object 추가할 때 사용하는 push 함수
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){
let num = state.findIndex((a)=>{return a.id === action.payload})
state[num].count++
},
addProduct(state, action){
state.push(action.payload) // list나 object 추가시엔 push 함수 사용, 여기선 JSON 추가됨
}
}
})
// 등호 오른쪽 자료에서 export할 자료 보냄
export let {increaseCount, addProduct} = cart.actions
export default cart
'React > 코딩애플 강의' 카테고리의 다른 글
[React] 컴포넌트 전환 애니메이션 (0) | 2023.07.10 |
---|---|
[React] axios 라이브러리를 이용한 ajax (0) | 2023.07.04 |
[React] Lifecycle과 useEffect (0) | 2023.07.04 |
[React] CSS를 대체할 수 있는 styled-components (0) | 2023.07.04 |
[React] find, findIndex, filter (0) | 2023.07.04 |