23/11/13 til react 숙련주차(4) 리덕스
2023. 11. 14. 15:08ㆍ카테고리 없음
컴포넌트 App.jsx
import React, { useState } from "react";
import { useDispatch, useSelector } from "react-redux"; // 스토어에 액션을 보내줄 디스패치와 스테이트값을
import { plus_one } from "./redux/config/modules/counter"; //받을 셀렉터를 임포트
import { minus_one } from "./redux/config/modules/counter";
import { PlusOne } from "./redux/config/modules/counter"; //나머지것들은 카운터라는 리듀서의 타입들
import { plusN } from "./redux/config/modules/counter";
import { minusN } from "./redux/config/modules/counter";
function App() {
const [number, setnumber] = useState(0); //요것은 인풋태그에 쓰일 유즈스테이트 요넘버를 페이로드로 넘김
const counter = useSelector((state) => { //유즈셀렉터를 통해 스테이트인자를 받아온다.
return state.counter; //스테이트는 리듀서인 카운터.js에서 온다.
}); //스테이트 중에서 카운터함수를 가져온다.
const dispatch = useDispatch();
console.log(counter.number); //유즈디스페치는 스토어에 다시 액션을 해줄 훅이다.
return (
<div>
<>현재카운트 : {counter.number}</> 중괄호안에 카운트넘버호출
<div> // 현재카운트에 카운터라는 리듀서의 넘버가 호출
<input
type="number" //인풋태그에 타입을 넘버로하면 더하기빼기 용이하다고함?!?
value={number} //밸류는 유즈스테이트의 넘버거
onChange={(e) => {
setnumber(+e.target.value); //온체인지 설정 //e앞에 플러스 기호는 넘버로 변환해주는 방식
}}
/>
</div>
<button
onClick={() => {
// dispatch({
// type: plus_one, //디스패치 객체 의 타입은 카운터 리듀서의 case와 같은 밸류를 가져야함
// });
// dispatch(PlusOne());
dispatch(plusN(number)); //인풋태그에 찍힐 넘버를 인자로 갖는 함수를 디스패치에
}} //넣어서 페이로드로 넘긴다.
>
+
</button>
<button
onClick={() => {
// dispatch({
// type: minus_one,
// });
dispatch(minusN(number));
}}
>
-
</button>
</div>
);
}
export default App;
밑에는 리듀서인 counter.js
export const plus_one = "PlusOne"; // 디스패치의 타입의 벨류가 되줄 이것들을 액션밸류라한다.
export const minus_one = "Minusone";
export const plus_N = "counter/plus_N"; //수많은 타입과 케이스를 바꿔줄수 없으므로
export const minus_N = "counter/minus_N"; //변수화 시켜서 변수명을 케이스와 타입에 넣는다.
export const PlusOne = () => {
return { // 요런 액션밸류들을 일일히 타이핑해주면 휴먼 에러가 날수 있으므로
type: plus_one, // 함수화 시켜버리고 함수를 디스패치에서 호출해서 휴먼에러 줄인다.
};
};
export const plusN = (payload) => { //온클릭태그에서 넘어온 넘버를 페이로드로 받아서
return { //객체의 키와 벨류로 넣는다.
type: plusN,
payload: payload,
};
};
export const minusN = (payload) => {
return {
type: minusN,
payload,
};
};
const initialState = { //요건 이니셜 스테이트로서 리듀서인 카운터함수의 초기스테이트
number: 0, //의 상태를 나타내는 객체형태
};
const counter = (state = initialState, action) => { //스테이트의 디폴트로 이니셜스테이트넣는다.
switch (action.type) { //카운터 함수는 인자로 스테이트와 액션을 갖는다.
case plus_one:
return { //스위치문에 익숙하지 않은데 머리 돈다.
number: state.number + 1, //케이스를 여러개로 할수 있다. 이중에 케이스명과
}; // 디스페치 객체의 변수명과 맞추기만 하면됨
case minus_one:
return {
number: state.number - 1,
};
case plusN: //타입과 일치하는 케이스 작동
return {
number: state.number + action.payload, //현재 스테이트의 키가 넘버인곳에 현재넘버에
}; //액션의 페이로드의 값을 더하는 것을 넘버에 재할당
case minusN:
return {
number: state.number - action.payload,
};
default:
return state;
}
};
export default counter;
밑에는 스토어인 configstore.js
import { createStore } from "redux";
import { combineReducers } from "redux";
import counter from "./modules/counter"; //리듀서인 카운터함수 임포트해야함
import users from "./modules/users"; //요것도 리듀서 유저스인데 테스트용
const rootReducer = combineReducers({
counter, //요게 리듀서를 스토어에 모으는 방식 객체형태
users: users, //키과 밸류가 같으면 카운터처럼 써도됨
});
const store = createStore(rootReducer); //크리에이트스토어 인자에 컴바인 리듀서 객체를 넣는다.
export default store;
밑에는 인덱스.js
import React from "react";
import ReactDOM from "react-dom/client";
import "./index.css";
import App from "./App";
import reportWebVitals from "./reportWebVitals";
import { Provider } from "react-redux"; //프로바이더 임표트해야함
import store from "./redux/config/configStore"; //스토어도 임포트 해야함 디폴트로 익스포트한거는 괄호가 읍슴
const root = ReactDOM.createRoot(document.getElementById("root"));
root.render(
<Provider store={store}> //앱 컴포넌트를 프로바이드로 감싸주고 소토어를 태그안에 넣어줘여
<App /> //리덕스 작동
</Provider>
);
// If you want to start measuring performance in your app, pass a function
// to log results (for example: reportWebVitals(console.log))
// or send to an analytics endpoint. Learn more: https://bit.ly/CRA-vitals
reportWebVitals();
어렵고 복잡하다.... 빙글빙글