//리덕스가 필요한 이유
//1.useState의 불편함
//어떤 컴포넌트에서 생성한 state를 다른 컴포넌트로 보고자 할 때 우리는
//props를 통해서 부모 컴포넌트에서 자식 컴포넌트로 그 값을 보냈음
//근데 Props로 State를 공유하는 방법에는 불편한 점이 있음
//하지만 디럭스는 중앙데이터관리소 역할을 함
//비슷한 기능으로 앞서 context를 배웠지만
//context는 props가 하나라도 변경되면 하위 컴포넌트 모두가 리렌더링 됐지만
//리덕스는 State를 공유하고자 할 때 부-모 관계가 아니여도 되고 중간에 의미 없이
//컴포넌트를 거치지 않아도 됨
//Global state 와 LocalState
//Local state란
//컴포넌트에서 useState를 이용해서 생성한 state 좁은 범위 안에서 생성된 state
//Global state
//Global state는 컴포넌트에서 생성되지 않음 중앙화 된 특별한 곳에서
//State들이 생성됨 ,쉽게 말해 중앙 state 관리소 라고 생각하면 됨
//리덕스란
//중앙 state 관리소를 사용할 수 있게 도와주는 패키지(라이브러리)
//리덕스는 **useState를 통해 상태를 관리했을 때 발생하는 불편함을 일부 해소**시켜준다.
//리덕스는 `중앙 State 관리소`를 가지고 있으며, 모든 State는 이곳에서 생성된다.
//**useState로 생성한 State는 Local State**이고, **리덕스에서 생성한 State는 Global State**이다.
//리덕스 설정
//리덕스 설치 명령어 yarn add redux // yarn add react-redux 두개를 설치
//터미널에 yarn add redux react-redux
//리덕스 폴더 구조
//`redux`(최상위) : 리덕스와 관련된 코드를 모두 모아 놓을 폴더 입니다.
//`config`(redux/config) : 리덕스 설정과 관련된 파일들을 놓을 폴더 입니다.
//`configStore.js(redux/config/configstore)` : “중앙 state 관리소" 인 Store를 만드는 설정 코드들이 있는 파일 입니다.
//`modules(redux/modules)` : 우리가 만들 State들의 그룹이라고 생각하면 됩니다. 예를 들어 `투두리스트`를 만든다고 한다면,
//투두리스트에 필요한 `state`들이 모두 모여있을 `todos.js`를 생성하게 되텐데요, 이 `todos.js` 파일이 곧 하나의 모듈이 됩니다.
//기본설정
//configstore.js
//중앙 데이터 관리소(store)를 설정하는 부분
//스토어 생성후 index.js에서 설정 해야함
//1.스토어 생성 configStore.js
import {createStore} from "redux"
import { combineReducers } from "redux"
import counter from "../modules/counter";//모듈에서 만든 리듀서 (함수코드)
const rootReducer =combineReducers({
//여기에는 modules 에서 만든 리듀서들이 추가됨
counter, //counter:counter 지만 키와 값이 같으면 한줄로 가능
});
const store =createStore(rootReducer)
export default store;
//2.index.js 에서 만든 스토어 설정하기
import {Provider} from 'react-redux'
//export default는 중괄호 없이 바로 import store 해야 함
import store from './redux/config/configStore'
const root = ReactDOM.createRoot(document.getElementById('root'));
root.render(//Provider로 APP을 감싸서 스토어 등록
<Provider store={store}>
<App />
</Provider>
);
//3. modules 에서 counter.js 만들기
//로컬state방식 => const [number, setNumber] =useState(0)
//글로벌 state 초기 상태값 (state)
const initiaState = {
number : 0
}
//리듀서 :'state에 변화를 일으키는' 함수
//(1)state를 action의 type에 따라 변경하는 함수
//input :state와 action 을 받는다
//아래 코드가 예시로 만든 리듀서임
//만든 리듀서는 스토어 (configstore)에 임포트와 root에 추가 해야 쓸 수 있음( counter 리듀서 만든 후 )
//1번으로 돌아가서 counter 추가 하기
const counter = (state=initiaState,action)=>{
switch (action.type){
default:
return ;
}
}
export default counter;
//4.등록한 스토어를 App.js 에서 사용해 보기
import React from 'react'
import { useSelector } from 'react-redux'
function App() {
//여기에서 store에 접근해 ,추가된 리듀서 사용 하는 코드 작성
//useSelector < 리덕스의 hook (접근하는 함수)
const couter = useSelector((state)=>{
//state 는 Store에 추가된 모든 리듀서를 가져옴
//특정 함수만 가져오고 싶으면 state.counter 이런식으로 가져 올 수 있음
return state.counter;
});
console.log("couter", couter.number)
return (
<div>App</div>
)
}
export default App
//redux -dispatch
//1.dispatch 가 Store에 action을 던진다
//2.Store는 dispatch의 action.type 에 따라 state 변경
//App.js
import React from 'react'
import { useDispatch } from 'react-redux';
import { useSelector } from 'react-redux'
function App() {
//여기에서 store에 접근해 ,추가된 리듀서(함수)
//useSelector < 리덕스의 hook (접근하는 함수)
const counter = useSelector((state)=>{
//state 는 Store에 추가된 모든 함수(리듀서)를 가져옴
//특정 함수만 가져오고 싶으면 state.counter 이런식으로 가져 올 수 있음
return state.counter;
});
//dispatch를 가져와 보자 리액트-redux hook
const dispatch =useDispatch();
console.log("couter", counter.number)
return (
<>
<div>현재 카운트 : {counter.number}</div>
<button onClick={()=>{
//+1을 해주는 로직을 써주면 된다.(모듈에 있는 맞는 type dispatch로 보낸다)
dispatch({
type:'Plus',
})
}}>+</button>
<button onClick={()=>{
//-1 을 해주는 counter.js의 type을 dispatch로 보낸다
dispatch({
type:'Minus'
})
}}>-</button>
</>
)
}
export default App
//ex)modules/ counter.js
//로컬state방식 => const [number, setNumber] =useState(0)
//글로벙 state 초기 상태값 (state)
const initiaState = {
number : 0
}
//리듀서 :'state에 변화를 일으키는' 함수
//(1)state를 action의 type에 따라 변경하는 함수
//input :state와 action 을 받는다
//아래 코드가 예시로 만든 리듀서임
//만든 리듀서는 스토어 (configstore)에 임포트와 root에 추가 해야 쓸 수 있음
const counter = (state=initiaState,action)=>{
switch (action.type){
case "Plus": //type이 Plus면 state에 +1 해주는 코드
//state가 오브젝트라 아래의 방법을 씀
return {number: state.number +1,}
case "Minus":
return {number: state.number-1}
default:
return state;
}
}
export default counter;