22.03.16 react-redux

홍왕열·2022년 3월 15일
0

TIL

목록 보기
28/56

react-redux

설치
npm install react-redux
yarn add react-redux

import { createStore } from "redux" 로 불러온다.

그리고 무조건 const store = createStore(reducer)를 만들어야 한다.

바로 저장소를 만드는 것이다.
그리고 안에 reducer를 만들어야 하는데, reducer는 유일하기 저장소의 값을 변경할 수 있는 함수라고 생각하면 된다.

reducer의 이름은 마음대로 바꿔도 된다.

reducer는 두 개의 인자가 들어온다.
currentState, action.

여기서 action은 나중에 나오는 useDispatch로 action에 접근하여 state값을 바꿀 수 잇는 것이고, currentState는 현재 state를 나타낸다.

초기값을 잡을 때는 currentState를 undefined이라고 가정하고 잡는 것도 필요한 것 같다.

또한 action에는 무조건 type이 들어와야 한다.

여기서 중요한 점은!!

redux는 각각의 state의 변화가 불변해야하기 때문에 무조건 복사를 해서 사용하거나 원본을 변화시키지 않는 새로운 객체 및 배열을 만드는 것이 중요하다.
그래서 spread나 filter함수를 사용한다.

function reducer(currentState, action) {
  //reducer에는 2개의 인자가 온다. 현재의 state값과 action!! //! return값이 새로운 state의 값이 된다.
  if (currentState === undefined) {
    return {
      number: 1, //number라는 state값이 기본적으로 1이다라고 지정!! undefined일 때 적용(약간 useState() 느낌, 초기값 정해주는 것 같은 느낌.)
    };
  }
  const newState = { ...currentState }; //redux는 각각의 state의 변화가 불변해야하기 때문에, 무조건 복사본을 사용한다!! 그렇기 때문에 spread 연산자를 사용하거나 filter를 사용한다.
  if (action.type === "PLUS") {
    //right3에서 useDispatch로 action에 접근하여 type을 지정했을 때, reducer는 그 action을 이용해서 state값을 변경시킬 수 있다.
    newState.number++;
  }
  return newState;
}
const store = createStore(reducer);

provider

Provider로 감싼 애한테 store를 전달해주겠다는 뜻.

만약 left1을 컴포넌트로 넣고 left1에 left2를 컴포넌트로 넣고 left3을 컴포넌트로 넣었을 때, left1만 Provider로 감싸줘도 left2와 left3에서 store의 사용이 가능하다.
여기서 중요한 점 !

Provider에는 store={store}가 꼭 들어가야 한다.

export default function App() {
  return (
    <div id="container">
      <h1>Root</h1>
      <div id="grid">
        <Provider store={store}>
          {/*반드시 Provider에는 store가 들어와야하는데, 그 store에는 우리가 지정한 store가 들어와야 하는 것이다. //! 아래 두 개의 컴포넌트에 전달해주겠다. */}
          <Left1></Left1>
          <Right></Right>
        </Provider>
      </div>
    </div>
  );
}

useSelector

useSelector를 쓴 곳에서 props로 받겠다 할 때 쓰는 것

useSelector는 함수를 인자로 받아야 한다.
변수 이름이나 useSelector에 들어오는 parameter 이름은 아무 상관이 없다.

const Left3 = (props) => {
  //   function f(state) {
  //     return state.number; //! state값에서 number를 쓰겠다. 아래 인자와 같은 함수
  //   }
  const number홍왕열 = useSelector((state김소라) => state김소라.number); // 여기서 App에서 props로 받겠다. //! useSelector는 함수를 인자로 받아야 한다. 변수 이름이나 useSelector에 들어오는 이름이나 아무 상관 없다.
  return (
    <div>
      <h1>Left3: {number홍왕열}</h1>{" "}
      {/*만약에 console.log로 부모와 함께 다르게 해서 찍어보았을 때, left3만 console.log가 찍힌다. 즉, 이것만 렌더링이 되고 부모는 렌더링이 되지 않는다. */}
    </div>
  );
};

export default Left3;

use Dispatch

action을 이용하여 reducer를 호출한다.

dispatch에는 무조건 type이 들어간다.

const Right3 = (props) => {
  const dispatch = useDispatch(); //action을 이용하여 reducer를 호출한다.
  return (
    <div>
      <h1>Right3</h1>
      <input
        type="button"
        value="+"
        onClick={() => {
          dispatch({ type: "PLUS" }); //dispatch에는 무조건 type이 들어가야 한다!! 
        }}
      />
    </div>
  );
};

전체 코드

import React, { useState } from "react";
import Left1 from "./Left";
import "./style.css";
import Right from "./Right";
import ReactDOM from "react-dom";
import { createStore } from "redux";
import { Provider, useSelector, useDispatch, connect } from "react-redux";
//Provider = 어떤 component들에게 제공할 것인가에 대한 가장 바깥쪽 울타리를 정의
//useSelector = 어느 component에 무선으로 연결하고 싶을 때 사용하는 것!! //! 지금 여기서는 Left3에 들어간다.

function reducer(currentState, action) {
  //reducer에는 2개의 인자가 온다. 현재의 state값과 action!! //! return값이 새로운 state의 값이 된다.
  if (currentState === undefined) {
    return {
      number: 1, //number라는 state값이 기본적으로 1이다라고 지정!! undefined일 때 적용(약간 useState() 느낌, 초기값 정해주는 것 같은 느낌.)
    };
  }
  const newState = { ...currentState }; //redux는 각각의 state의 변화가 불변해야하기 때문에, 무조건 복사본을 사용한다!! 그렇기 때문에 spread 연산자를 사용하거나 filter를 사용한다.
  if (action.type === "PLUS") {
    //right3에서 useDispatch로 action에 접근하여 type을 지정했을 때, reducer는 그 action을 이용해서 state값을 변경시킬 수 있다.
    newState.number++;
  }
  return newState;
}
const store = createStore(reducer);

export default function App() {
  return (
    <div id="container">
      <h1>Root</h1>
      <div id="grid">
        <Provider store={store}>
          {/*반드시 Provider에는 store가 들어와야하는데, 그 store에는 우리가 지정한 store가 들어와야 하는 것이다. //! 아래 두 개의 컴포넌트에 전달해주겠다. */}
          <Left1></Left1>
          <Right></Right>
        </Provider>
      </div>
    </div>
  );
}
//APP.js
import React from "react";
import "./style.css";
import ReactDOM from "react-dom";
import { createStore } from "redux";
import { Provider, useSelector, useDispatch, connect } from "react-redux";

const Right3 = (props) => {
  const dispatch = useDispatch(); //action을 이용하여 reducer를 호출한다.
  return (
    <div>
      <h1>Right3</h1>
      <input
        type="button"
        value="+"
        onClick={() => {
          dispatch({ type: "PLUS" }); //dispatch에는 무조건 type이 들어가야 한다!! 
        }}
      />
    </div>
  );
};

export default Right3;
//right3
import React from "react";
import "./style.css";
import ReactDOM from "react-dom";
import { createStore } from "redux";
import { Provider, useSelector, useDispatch, connect } from "react-redux";

const Left3 = (props) => {
  //   function f(state) {
  //     return state.number; //! state값에서 number를 쓰겠다. 아래 인자와 같은 함수
  //   }
  const number홍왕열 = useSelector((state김소라) => state김소라.number); // 여기서 App에서 props로 받겠다. //! useSelector는 함수를 인자로 받아야 한다. 변수 이름이나 useSelector에 들어오는 이름이나 아무 상관 없다.
  return (
    <div>
      <h1>Left3: {number홍왕열}</h1>{" "}
      {/*만약에 console.log로 부모와 함께 다르게 해서 찍어보았을 때, left3만 console.log가 찍힌다. 즉, 이것만 렌더링이 되고 부모는 렌더링이 되지 않는다. */}
    </div>
  );
};

export default Left3;
//left3
profile
코딩 일기장

0개의 댓글