관리 메뉴

공부기록용

React숙련주차11(Redux hook_useSelector/usedispatch) 본문

📚강의록📚/스파르타)React

React숙련주차11(Redux hook_useSelector/usedispatch)

과부하가즈아 2023. 6. 30. 23:31

🔴모듈

🔴useSelector

🔴usedispatch


모듈

모듈이란, State의 그룹

counter.js_즉, state라는 뜻이지

// src/modules/counter.js

// 초기 상태값
const initialState = {
  number: 0,
};

// 리듀서
const counter = (state = initialState, action) => {
  switch (action.type) {
    default:
      return state;
  }
};

// 모듈파일에서는 리듀서를 export default 한다.
export default counter;

initialState === 초기 상태값
어떤 State의 초기값을 정해주는 것
// 초기 상태값
const initialState = {
  number: 0,
};

// useState의 
const [number, setNumber] = useState(0)
// 와 같은 이치​

초기값은 꼭 객체가 아니어도 된다. 배열이 되어도 되고, 그냥 원시데이터도 된다. 그리고 객체에도 여러개의 변수를 넣어줄 수 있다.
// 초기값이 0
const initialState = 0;

// 초기값이 0이 있는 배열 
const initialState = [0];

// 초기값이 number = 0, name = '석구'인 객체
const initialState = {
	number: 0,
	name: '석구'
};​

Reducer === 변화를 일으키는 함수

해당 코드를 리듀서라고 한다. 리듀서란, 변화를 일으키는 함수이다.

// 리듀서 
const counter = (state = initialState, action) => {
  switch (action.type) {     // switch문_action에 있는 type에 따라서 {조건}의 작업을 수행할 것이다.
    default:
      return state;
  }
};​

state를 action의 type에 따라 변경하는 함수이다.
>인자로 state, action을 받음
> state의 초기값은 initialState라고 위에 초기 값을 지정해준거에 붙여 써준다.
> 인자로 받는 action은 type과 value를 가진 객체 형태로 되어 있음
> action은 state를 어떻게 할건지에 대한 action을 표현하는 것


export

export default counter;

> 모듈파일에서는 리듀서를 export default 한다.


각 컴포넌트에서 중앙저장소(store)에 저장되어 있는 state를 가져다 쓰기 위해서 redux에서 제공하는 hook을 이용해야 한다

useSelector

전반적인 흐름 이해

 > 즉 생성한 모듈을 스토어에 잘 연결했는지 확인이 필요하다. 컴포넌트에서 스토어를 직접 조회하면 되는데 컴포넌트에서 리덕스 스토어를 조회하고자 할때는 useSelector이라는 redux hook을 사용해야 한다. 

// src/modules/counter.js

const initialState = {
    number: 0,
};

const counter = (state = initialState, action) => {
    switch (action.type) {                 // switch문_action에 있는 type에 따라서 {조건}의 작업을 수행할 것이다.
        default:
            return state;
    }
};

// 모듈파일에서는 리듀서를 export default 한다.
export default counter;

+

// src/modules/user.js

const initialState = {
    userId: 123,
};

const users = (state = initialState, action) => {
    switch (action.type) {
        default:
            return state;
    }
};

// 모듈파일에서는 리듀서를 export default 한다.
export default users;

// 중앙 데이터 관리소(store)를 설정하는 부분

import { createStore } from "redux";
import { combineReducers } from "redux";

import counter from "../modules/counter";
import users from "../modules/users";


const rootReducer = combineReducers({
    counter: counter,
    users: users,
}); 

const store = createStore(rootReducer); 

export default store;

useSelector

사용해서 App.jsx에서 정보 조회하기(컴포넌트에서 스토어를 조회)

// src/App.jsx
import React from 'react'
import { useSelector } from 'react-redux'

function App() {

  // useSelector사용
  // 여기에서 store로 접근하여, counter의 값을 읽어오고 싶다면?
  
  const counter = useSelector(function(state){
    return state.counter;
  });

  console.log("counter ->", counter.number);
  
  return (
    <div>Redux</div>
  )
}

export default App

View 에서 액션이 일어난다.

  1. dispatch 에서 action이 일어나게 된다.
  2. action에 의한 reducer 함수가 실행되기 전에 middleware가 작동한다.
  3. middleware 에서 명령내린 일을 수행하고 난뒤, reducer 함수를 실행한다. (3, 4번은 아직 몰라도 됩니다!)
  4. reducer 의 실행결과 store에 새로운 값을 저장한다.
  5. store의 state에 subscribe 하고 있던 UI에 변경된 값을 준다.
dispatch
UI(컴포넌트)에서 action객체를 가지고 store에 던져주는 역할을 한다.

즉, 중앙 데이터 관리소에 데이터를 동작시키는 action을 요청해주는 것, 그럼 store에서 action 객체에 있는 type에 따라서 reducer가 state를 제어하는 것이다(state를 변경해주는 작업을 )


action
key value로 이루어진 객체이고, key로써 action type와 payload를 가진다. 

usedispatch

액션객체를 보내기 리듀서로 보낸다. react-redux에서 import 해서 사용할 수 있으며, 우리가 만든 액션 객체를 리듀서로 보내주는 역할을 하는 훅이다.

 

리듀서에게 보낼 “명령” 만들기

// src/App.js
import React from 'react'
import { useSelector, useDispatch } from 'react-redux'

function App() {

  // dispatch를 가져오기
  const dispatch = useDispatch();


  console.log("counter ->", counter.number);

  return (
    <>
      <div>현재 카운트 : {counter.number}</div>

      <button onClick={function () {
        dispatch({
          type: 'PLSH_ONE',
          payload: ''
        })
      }}>+</button>

      <button onClick={function () {
        dispatch({
          type: 'MINUS_ONE',
          payload: ''
        })
      }}>-</button>

    </>

  )
}

export default App
액션 객체는 반드시 type이라는 key를 가져야 한다. 왜냐하면 우리가 이 액션 객체를 리듀서에게 보냈을 때 리듀서는 객체 안에서 type이라는 key를 보기 때문이다.

앞으로 우리는 리덕스 모듈에 있는 state을 변경하기 위해서는 그에 해당하는 액션 객체를 모두 만들어줘야 한다.
  const dispatch = useDispatch();

> useDispatch라는 훅을 사용하기 위해서 컴포넌트 안에서 코드를 작성해서 dispatch라는 변수를 생성해줘야 한다.

> 생성한 dispatch는 함수이므로 우리는 dispatch를 사용할 때 () 를 붙여서 함수를 실행하게 된다.

> 그리고 dispatch를 사용할 때 ( ) 안에 액션객체{ }를 넣어주면 된다.

> 디스패치를 이용해서 액션객체를 리듀서로 보냈다.


액션 객체 받기

// src/modules/counter.js

const initialState = {
    number: 0,
};

const counter = (state = initialState, action) => {
    switch (action.type) {                
    // PLUS_ONE이라는 case를 추가한다.
    // 여기서 말하는 case란, action.type을 의미한다.
    // dispatch로부터 전달받은 action의 type이 "PLUS_ONE" 일 때
    // 아래 return 절이 실행된다. 
        case "PLSH_ONE":
            return {
                number: state.number +1
            }
        case "MINUS_ONE":
            return {
                number: state.number -1
            }

        default:
            return state;
    }
};

// 모듈파일에서는 리듀서를 export default 한다.
export default counter;

> action이 {type: “PLUS_ONE”} 이기 때문에, 리듀서 안에 있는 스위치문은 action.type을 조회한다.

> 그리고 그것이 일치하면 return 절이 실행되고 새로운 state를 반환합니다.

> 스위치문에 case를 하나 추가해주는 것으로 완료됩니다.

 

dispatch를 통해 액션객체를 App.js 컴포넌트에서 보냈고, 그것을 리듀서에서 받아 스위치문을 통해 조건을 찾았고, 그에 해당했을 때 state값을 변경하는 로직까지 모두 구현된 것

 

// src/App.js
import React from 'react'
import { useSelector, useDispatch } from 'react-redux'

function App() {

  // useSelector사용
  // 여기에서 store로 접근하여, counter의 값을 읽어오고 싶다면?

  const counter = useSelector(function (state) {
    return state.counter;
  });

  // dispatch를 가져오기
  const dispatch = useDispatch();


  console.log("counter ->", counter.number);

  return (
    <>
      <div>현재 카운트 : {counter.number}</div>

      <button onClick={function () {
        dispatch({
          type: 'PLSH_ONE',
          payload: ''
        })
      }}>+</button>

      <button onClick={function () {
        dispatch({
          type: 'MINUS_ONE',
          payload: ''
        })
      }}>-</button>

    </>

  )
}

export default App


  • 액션객체란, 반드시 type이란 key를 가져야 하는 객체이다. 또한 리듀서로 보낼 “명령"이다.
  • 디스패치란, 액션객체를 리듀서로 보내는 “전달자” 함수이다.
  • 리듀서란, 디스패치를 통해 전달받은 액션객체를 검사하고, 조건이 일치했을 때 새로운 상태값을 만들어내는 “변화를 만들어내는" 함수이다.
  • 디스패치(dispatch)를 사용하기위해서는 useDispatch() 라는 훅을 이용해야 한다.
    • 디스패치는 스토어의 내장함수 중 하나입니다.
    • 우선, 디스패치는 액션을 발생 시키는 것 정도로 이해하시면 됩니다.
    • dispatch 라는 함수에는 액션을 파라미터로 전달합니다.. dispatch(action) 이런식으로 말이죠.
  • 액션객체 type의 value는 대문자로 작성한다. (JS에서 상수는 대문자로 작성하는 룰이 있음)
Comments