Redux가 뭔데 왜 쓰는데
Redux는 props 없이 state를 공유할 수 있게 도와주는 라이브러리이다.
store.js에 state들을 보관하고 다른 컴포넌트에 쏴줄수있다.
사이트가 커지면 유용하게 써먹을 수 있다.
Redux 설치 및 셋팅
Redux 설치
아래의 코드를 터미널에 입력하면된다.
npm install @reduxjs/toolkit react-redux
redux toolkit이라는 라이브러리를 사용할 건데 redux의 문법을 쉽게 만드는 라이브러리이다.
설치하기전에
"react"
"react-dom"
의 버전이 18.1.x 이상인지 확인하자.
확인법은 package.json에서 확인가능하다.
Redux 셋팅
아무곳에 store.js 파일을 만들고 아래 코드에 복붙해준다.
여기가 바로 state를 보관하는 파일이다.
import { configureStore } from '@reduxjs/toolkit'
export default configureStore({
reducer: { }
})
index.js파일에 들어가서
Provider와 store를 import해온다.
밑에 <Provider store={import해온거}> 이걸로 <App/> 을 감싸면 된다.
이러면 store.js에 있던 state를 맘대로 꺼내 쓸수있다.
import { Provider } from "react-redux";
import store from './store.js'
const root = ReactDOM.createRoot(document.getElementById('root'));
root.render(
<React.StrictMode>
<Provider store={store}>
<BrowserRouter>
<App />
</BrowserRouter>
</Provider>
</React.StrictMode>
);
store에 보관하는 법
createSlice(), configureStore() import해오기
1. createSlice()로 state만들기
{ name : 'state이름', initialState : 'state값' }
2. configureStore()안에 등록
{ 작명 : createSlice만든거변수명.reducer }
(store.js)
import { configureStore, createSlice } from '@reduxjs/toolkit'
let user = createSlice({
name : 'user',
initialState : 'kim'
})
export default configureStore({
reducer: {
user : user.reducer
}
})
store에 있는거 가져다 쓰는법
useSelector import해오기
let a = useSelector((state) => state.user ) 로 가져와서 쓰면된다.
(Cart.js)
import { useSelector } from "react-redux"
function Cart(){
let a = useSelector((state) => state.user )
console.log(a)
return (생략)
}
store에 있는 state 변경하는법
store에 state변경함수를 만들어서
컴포넌트에서 state변경함수를 통해서 state변경시키면된다.
뭔소리인지 모르겠으면 밑에 설명을 보자.
store.js에 state변경함수 만들기
1. reducers : { } 안에 함수를 만들어준다.
2. 함수명은 자기 맴
3. 파라미터는 기존의 state가 된다. (여기서 "kim")
4. return 우측 새로운 state입력하면 state 바꿔준다. ("kim" => "john kim")
5. export해준다.
let user = createSlice({
name : 'user',
initialState : 'kim',
reducers : {
changeName(state){
return 'john ' + state
}
}
})
export let { changeName } = user.actions
state변경함수 import해서 사용하기
store.js에서 원하는 state변경함수 가져온다.
useDispatch 라는 것도 라이브러리에서 가져온다.
그리고 dispatch( state변경함수() ) 이렇게 감싸서 실행하면 state 진짜로 변경된다.
Cart.js)
import { useDispatch, useSelector } from "react-redux"
import { changeName } from "./../store.js"
(생략)
<button onClick={()=>{
dispatch(changeName())
}}>버튼임</button>
state가 object/array일 경우 변경하는 법
redux state가 {name : 'kim', age : 20}처럼 생긴 자료를 name: "park"으로 변경하고싶다면 어떻게 해야할까?
밑의 코드처럼 state전체를 바꾸는 방법이 있다.
let user = createSlice({
name : 'user',
initialState : {name : 'kim', age : 20},
reducers : {
changeName(state){
return {name : 'park', age : 20}
}
}
})
하지만 전체코드를 바꾸는것보다는 하나를 불러와서 바꿔주는게 낫다.
let user = createSlice({
name : 'user',
initialState : {name : 'kim', age : 20},
reducers : {
changeName(state){
state.name = 'park'
}
}
})
state변경함수에 파라미터를 넣고싶다면 파라미터문법 사용
changeName의 두 번째 파라미터에 action을 넣고 action.payload를 넣어보자.
export해주고
(store.js)
let user = createSlice({
name : 'user',
initialState : {name : 'kim', age : 20},
reducers : {
changeName(state, action){
state.name = action.payload
}
}
})
export let { changeName } = user.actions;
Cart.js에서 import해오고
changeName("바꾸고 싶은 이름")으로 코드를 짜면
user.name이 "바꾸고 싶은 이름"에 넣은 글자로 변경되는것을 확인할 수 있다.
(Cart.js)
import { changeName } from "./../store.js";
<button
onClick={(a, i) => {
dispatch(changeName("cho"));
}}
>
버튼임
</button>
문제풀기
이거해봐야 좀 이해가 된다.
1. 수량 + 1 기능만들기
state에 있는 count를 버튼을 누르면 +1 되게하는 기능을 만들어보자.
let cart = createSlice({
name : 'cart',
initialState : [
{id : 0, name : 'White and Black', count : 2},
{id : 2, name : 'Grey Yordan', count : 1}
]
})
findIndex()나 find()를 사용해서 a.id === action.payload가 같은 객체만 가져오도록했다.
여기서 a는 state에 저장된 객체하나하나를 말하고
action.payload는 나중에 보낸 state변경함수에 파라미터로 들어가는 값이다.
(store.js)
let cart = createSlice({
name : 'cart',
initialState : [
{id : 0, name : 'White and Black', count : 2},
{id : 2, name : 'Grey Yordan', count : 1}
],
reducers : {
addCount(state, action){
let 번호 = state.findIndex((a)=>{ return a.id === action.payload })
state[번호].count++
}
}
})
(Cart.js)
dispatch(addCount(state.cart[i].id))
2. 주문버튼누르면 state에 새로운 상품추가
state변경함수를 여러개 사용해서 추가해보자.
기존의 state에 push를 이용해서 추가하는 방식이다.
export도 추가해주자.
(store.js)
let cart = createSlice({
name : 'cart',
initialState : [
{id : 0, name : 'White and Black', count : 2},
{id : 2, name : 'Grey Yordan', count : 1}
],
reducers : {
addCount(state, action){
state[action.payload].count++
},
addItem(state, action){
state.push(action.payload)
}
}
})
export let { increace, addItem } = cart.actions;
cart.js에서 import해오고
addItem()함수에 파라미터로 넣고싶은 상품 정보를 넣어주자.
(Cart.js)
import { increace, changeName, addItem } from "./../store.js";
<button
onClick={() => {
dispatch(
addItem({ id: { i }, name: "Red knit", count: 1 })
);
}}
>
물품추가
</button>
'개발 > React' 카테고리의 다른 글
내가 React를 선택한 이유 (1) | 2023.11.25 |
---|---|
실시간 데이터가 중요하면 react-query (0) | 2023.08.26 |
props가 귀찮다면 Context API (이거보단 Redux가 좋아) (0) | 2023.08.23 |
Lifecycle과 useEffect (0) | 2023.08.18 |
styled-components 라이브러리 설치 및 간단한 사용법 (0) | 2023.08.18 |
댓글