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();

 

어렵고 복잡하다.... 빙글빙글