- state 만든 데 가서 수정하는 함수 만들기
- 만든 함수를 export 해주기
- import해서 사용하는데 useDispatch() 안에다가 쓴다
let user = createSlice({
name : 'user' , // state 이름
initialState : 'kim', //state 값
reducers : {
changeName(state){
return 'john ' + state
}
}
reducers 안에 넣어 줘야 함. 이것도 객체 형태로 들어간다
이 변경함수들은 return 하고 새로운 값을 넣어주면 이 값으로 기존 state를 갈아치워 준다.
여기서 기존 state 의 값이 필요한 경우 파라미터 하나 추가하면 기존 state를 출력함!
만든 함수를 export 해줘야 다른데 가서 쓸수있으니
export 할때
changeName(state){
return 'john ' + state
},
요 상태로는 export가 안 되니까
user.actions 하면 reducers : { } 안에 있는 애들이 남는다.
원래는 변수 선언하고 내보내야 되는데 관습적으로 이렇게 쓴다.
export 하고싶은 함수명들을 이렇게 다 적어줌
export let { changeName , func1 , func2 } = user.actions
이런 식으로 쓴다
이것도 destructuring 문법임
오른쪽에 있는 자료를 변수로 빼는 거
-> 아 이해됨!!!
아래 GPT 답변에서 얘기해준 거: user.actions는 유저가 만든 함수들이 들어가 있는 객체
그러니까 그 객체에서 키값이 changeName인 애를 뽑아와서 export해라~~ 라는 뜻인듯!
import 하고나서 useDispatch() 라는 함수도 필요함
이건 변수에 저장해서 쓴다
import { useSelector , useDispatch } from "react-redux";
import { changeName } from "./../store.js";
let state = useSelector((state)=>{return state})
let dispatch = useDispatch(); // 이거
//중략
<button onClick={()=>{
dispatch(changeName())
}}> + </button>
useDispatch()는 store.js 한테 요청 보내주는 함수.
dispatch( state 수정함수() ) 이렇게 감싸줘야 함.
작동 방식
store.js 에 수정함수를 만들고
컴포넌트에서 state 변경이 필요하면 store.js에
수정함수 좀 실행해주세요~ 하고 부탁함
-> dispatch로 실행해달라고 메세지를 보낸다.
실제 함수 실행은 store.js 가 해주는 것.
왜이렇게하는건데?
ㄴ 모든 컴포넌트들이 store.js에 있는 state 를 맘대로 갖다 쓰면 어디서 버그가 났는지 찾기가 너무 힘들다 (모든 컴포넌트를 다 뒤져봐야 하니까)
그래서 store.js 안에 있는 수정함수에 부탁하는 식으로 하면 훨씬 버그 추적이 쉽다.
store.js만 뒤지면 되니까
(정처기 공부할 때,,, 게터/세터 메서드 만드는 이유랑 비슷한 듯)
여기서 생긴 의문점,,,
state 는 따로 import 하지 않아도 자동으로 useSelector 가 가져와 주는데, 왜 함수는 따로 import 를 해야 쓸 수 있나?
이게 궁금했다.
store.js
import { configureStore , createSlice } from '@reduxjs/toolkit'
let user = createSlice({
name : 'user' ,
initialState : 'kim',
reducers : {
changeName(state){
return 'john ' + state
},
export let { changeName } = user.actions;
export default configureStore({
reducer: {
user : user.reducer,
stock : stock.reducer,
cart : cart.reducer,
}
})
왜 따로 export 하는지도 궁금하긴 했는데
이건 함수 묶음/state 묶음을 따로 놓는 게 더 편리할 것 같아서 분리한 것 같다고 생각했음.
아무튼 다른 컴포넌트에서 가져다 쓸 때,
state 가져올때는
import { useSelector } from "react-redux";
let state = useSelector((state)=>{return state})
이렇게 useSelector 만 가져와도 됐다.
import { useSelector , useDispatch } from "react-redux";
import { changeName } from "./../store.js";
let dispatch = useDispatch();
// 중략
dispatch(changeName())
근데 함수는 따로 import 해야지 쓸수있어서?? 왜그런건지 GPT한테 물어봤다.
좋은 질문이에요! Redux에서 state와 action을 가져오는 방식이 다르기 때문에 생기는 의문입니다. 이를 이해하기 위해 Redux의 작동 원리와 useSelector, useDispatch의 역할을 살펴보겠습니다.
Redux의 구조는 크게 두 가지 요소로 나뉩니다:
store에 저장된 상태입니다. React 컴포넌트에서는 이 상태를 useSelector를 사용하여 읽을 수 있습니다.action은 단순히 어떤 일이 일어날지를 설명하는 객체입니다. 예를 들어, 아래와 같은 changeName 같은 함수는 action 객체를 생성해주는 역할을 합니다.useSelector와 useDispatch의 역할 차이useSelectoruseSelector는 store의 state를 읽기 위해 사용됩니다. 이는 Redux store에서 데이터를 가져오는 역할만 하며, 내부적으로는 store.getState()를 호출합니다.
state는 store 안에 전역적으로 저장되기 때문에, useSelector만 있으면 특정 컴포넌트에서 Redux의 상태를 읽을 수 있습니다.let state = useSelector((state) => state.user);위 코드는 state.user 값을 가져옵니다.useDispatchuseDispatch는 action을 store에 전달하기 위해 사용됩니다. Redux는 상태를 직접 수정하는 것이 아니라 action을 dispatch해야 상태를 변경합니다. 여기서 중요한 점은 useDispatch는 단순히 "action을 발생시키는 메커니즘"일 뿐, action 자체를 관리하거나 생성하지 않습니다.
state와 action의 가져오는 방식의 차이Redux의 state는 전역적으로 store에 저장됩니다. 따라서, useSelector는 Redux가 관리하는 store에 접근하여 필요한 데이터를 가져올 수 있습니다.
action은 단순히 Redux가 처리할 명령의 "설명"일 뿐입니다. 예를 들어, changeName 함수는 다음과 같이 동작합니다:
changeName() -> { type: "user/changeName" }
이 함수는 단지 Redux가 이해할 수 있는 action 객체를 반환하는 역할을 합니다. Redux store는 이 action 객체를 보고 "어떤 상태를 변경해야 하는지"를 판단합니다.
이러한 action 함수는 Redux store 자체에 저장되지 않으며, 별도로 모듈화되어 있습니다. 즉, action을 사용하려면 해당 함수를 명시적으로 import 해야 합니다.
store에 중앙 집중적으로 저장되며, useSelector가 이를 전역적으로 관리합니다. 모든 컴포넌트에서 같은 state를 공유하기 때문에 store만 연결되면 자동으로 접근할 수 있습니다.따라서:
import { changeName } from "./../store.js";
처럼 명시적으로 가져와야만 사용 가능합니다.
Redux에서 createSlice를 사용하면, reducers에 정의된 함수들은 자동으로 actions 객체에 저장됩니다. 예를 들어:
let user = createSlice({
name: "user",
initialState: "kim",
reducers: {
changeName(state) {
return "john " + state;
},
},
});
console.log(user.actions); // { changeName: ƒ }
이렇게 user.actions 안에 각 reducer와 동일한 이름의 action 생성 함수가 만들어집니다. 이를 export하는 이유는:
1. 다른 파일에서도 쉽게 사용하기 위해.
2. 코드를 모듈화하고 관리하기 위해.
state는 Redux store에 저장되어 있으므로 useSelector를 사용해 자동으로 가져올 수 있습니다.action은 Redux의 상태 변경을 트리거하는 역할을 하는 함수이며, 별도로 import해서 사용해야 합니다.createSlice는 reducers에 정의된 함수를 자동으로 actions 객체에 넣어줍니다. 이 함수를 export해서 사용할 수 있습니다.state와 action의 동작이 다른 이유는 Redux의 설계 원리 때문입니다:state는 전역적으로 관리되고,action은 단순히 상태를 변경하기 위한 "설명" 역할만 하기 때문입니다.내가 이해한게 맞다면
state는 store에 보관되는 게 맞는데,
함수는 store에 보관되는 게 아니다.
인 듯.
그래서 store에서 바로 가져다 쓸 수 있는 게 아니라 따로 가지고 와야 하는 것.
하긴 이래야 효율적일 듯!
함수들까지 굳이 모든 컴포넌트가 다 갖다 쓸 필요는 없는 거지.