redux를 쓰는 이유는 props로 당겨오기 귀찮고 보기도 힘들기 때문에 쓴다.
일단
터미널에
npm install @reduxjs/toolkit react-redux
작성해서 redux 다운로드하고
store.js 파일 만들어서 redux의 state를 담는 통을 만들어 줍니다.
import { configureStore } from '@reduxjs/toolkit'
export default configureStore({
reducer: { }
})
만들고 위의 내용을 복사 붙여넣기를 해줍니다.
다음에는
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>
);
위처럼
import { Provider } from "react-redux";
import store from './store.js'
이것도 추가해주고
<Provider store={store}> <BrowserRouter> <App /> </BrowserRouter> </Provider>
provider store={store}을 추가해서 감싸줍니다.
import { configureStore, createSlice } from '@reduxjs/toolkit'
let user = createSlice({
name : 'user',
initialState : 'kim'
})
export default configureStore({
reducer: {
user : user.reducer
}
})
사용할 변수 이름을 정하고 createSlice안에 정보를 넣어준 뒤
꼭 reducer안에 넣어줘야 합니다.
그 후에
import { useSelector } from "react-redux"
function Cart(){
let asd = useSelector((state) => { return state } )
console.log(a)
return (생략)
}
사용하고자 하는 파일에 가서 import { useSelector } from "react-redux" 와
let asd = useSelector((state) => { return state } )을 넣어주면
console.log(asd)을 넣으면 user가 나옵니다.
redux로 state변경하고 싶으면 위의 3개를 명심합시다.
let user = createSlice({
name: "user",
initialState: "kim",
reducers: {
changeName(state) {
return "john" + state
},
},
})
해당코드처럼 reducers 안에 바꿀 이름(changeName)을 넣어주고
수정할 스테이트를 넣어주면 됩니다.
참고로 changeName파라미터는 이전 state입니다.
여기서는 kim이 되겠네요.
파라미터로 뚫어놓으면 return할떄도 쓸 수 있습니다.
지금return john kim이 되겠네요.
2.이제 export해줍시다.
export let { changeName } = user.actions
이렇게 같은 페이지에서 export해주고
이제는
원하는 페이지에서 import해줍니다.
import { changeName } from "./store.js"
import해온 후에
import { useDispatch, useSelector } from "react-redux"
import한 페이지에서 useDispatch를 import해온 후에
let dispatch = useDispatch()
를 원하는 컴포넌트에 입력한 후에
<button
onClick={() => {
dispatch(changeName())
}}
>
전 버튼을 누르면 changeName을 변경 하게 만들었습니다.
redux로 state변경하기 끝입니다.
사실 dispatch는 실행을 하는게 아닌 부탁이라고 보는게 좀 더 맞는 표현같습니다.
즉 changeName실행해주세요 라고 요청을 보내는 거죠
왜 이렇게 복잡한 방법을 쓸까요??
이렇게 복잡하게 안쓰고 props로 수정하는게 더 편해 보이지만
복잡한 이유가 있습니다.
만약 각각의 페이지가 스스로 수정을 한다고 생각해 봅시다.
그럼 changeName이 문제가 생겼 을때 각각의 페이지를 다 뒤져야 됩니다.
왜냐면 각각 바꿨는데 사용하니까 원치 않는 답이 나오잖아요.
그럼 changeName을 바꾼 페이지가 100개면 100개 다 뒤져서 원인을 찾아야 되는데
이럴거면 redux안쓰고 props쓰죠.
이런 이유가 있습니다.
let user = createSlice({
name: "user",
initialState: { name: "kim", age: 20 },
reducers: {
changeName(state) {
return { name: "park", age: 20 }
},
},
})
그냥 이렇게 짜면 됩니다.
당연한걸 왜 적어놨지?
라는 생각이 들면 정답입니다.
근데 redux는 좀 더쉬운 방법이 있습니다.
let user = createSlice({
name: "user",
initialState: { name: "kim", age: 20 },
reducers: {
changeName(state) {
state.name = "park"
},
},
})
이렇게 직접적으로 바꿔줘도 바뀝니다.
저는 당연히 되는줄 알았는데
Immer.js라는 라이브러리가 redux 다운로드할때 같이 깔려서 쓸 수 있다고
하네요.
근데 이렇게 쓰면 편하지 않나요?
그래서 하나밖에 없어요 {name:"kim"}이렇게 짜기도 한다고 합니다.
근데 버튼을 만들어서 누르면 age가 올라가서 화면에 나오게
하고 싶어지면
let user = createSlice({
name: "user",
initialState: { name: "kim", age: 20 },
reducers: {
changeName(state) {
state.name = "park"
},
increase(state) {
state.age = state.age + 1
},
},
})
이렇게 짜면 button누를때마다 숫자가 올라갑니다.
근데 짜고나서 보니까
갑자기 10씩 올리고 싶으면 어떡하나요.
let user = createSlice({
name: "user",
initialState: { name: "kim", age: 20 },
reducers: {
changeName(state) {
state.name = "park"
},
increase(state, a) {
state.age = state.age + a.payload
},
},
})
이렇게 짜면 됩니다.
payload를 꼭 넣어주셔야 됩니다.
이렇게 적고
사용하고 싶은 페이지에서
<button
onClick={() => {
dispatch(increase(10))
}}
>
버튼
</button>
이렇게 적으면 10씩 올라갑니다.
참고로 payload는 택배,화물 이런 뜻입니다.