React-redux

FE 개발자 신상오·2022년 7월 6일
0

React

목록 보기
7/10
post-thumbnail

Redux

컴포넌트간 연결 없이 전역에서 상태를 관리할 수 있게 해주는 JS 라이브러리

1. Action
어떤 액션을 취할 것인지 정의해놓은 객체
2. Dispatch
Action -> Reducer 전달해주는 함수
3. Reducer
Dispatch로부터 받은 Action 객체의 type 값에 따라서 상태를 변경시키는 함수
4. Store
상태가 관리되는 오직 하나뿐인 저장소의 역할
Redux앱의 state가 저장되어 있는 공간

Action → Dispatch → Reducer → Store 순서의 단방향 데이터흐름을 가진다

Redux 사용법

1. 설치
npm install redux react-redux

2. import
react-redux 기능들 import
import {Provider, useSelector, useDispatch, connect} from 'react-redux'

3. createStore
저장소 store 생성
반드시 reducer가 인자로 들어가야함

import { createStore } from 'redux';
const store = createStore('리듀서 함수가 들어옴')

4. reducer
store안의 state를 어떻게 변경할지에 대한 함수
두개의 매개변수를 가짐 (현재state값, state를 어떻게 바꿀 것인지 action)
각각 state값을 불변하게 관리해야하기 때문에 새로운 state를 만들어서 관리

fuction reducer(curState, action) {
  // curState값이 없을 경우에는 기본값을 return 해주면 됨
  if (curState === undefined){
    return {
      number : 1
    }
  const newState = {...curState}
  
  if (action.type === 'PLUS'){
    newState.number++;
  }
  return newState

5. Provider state 필요한 컴포넌트 감싸기

  • Provider
    state들을 어떤 컴포넌트에 제공할 것인가에 대한 경계를 지정해줌
    props로 store를 내려줌
<Provider store={store}>
  state 사용할 컴포넌트들
</Provider>

6. useSelector로 state를 변수로 관리
useSelector는 매개변수로 state가 들어오면서 state의 value를 리턴하는 함수를 가진다

function Left3(props) {
  function f(state) {
    return state.number;
  }
  const number = useSelector(f);
  //const number = useSelector((state) => {return state.number})
  return (
    <div>
      <h1>Left3 : {number}</h1>
    </div>
  );
}

7. dispatch로 action을 reducer 함수에 전달

  • useDispatch();
    dispatch를 사용하기 위한 함수
// 컴포넌트 내부에 작성
function Right3(props) {
  const dispatch = useDispatch();
  return (
    <div>
      <h1>Right3</h1>
      <button onClick={() => {
        dispatch({ type: 'PLUS'})
      }}> + </button>
    </div>
  );
}

Redux 사용예시

right3 컴포넌트에서 left3 state를 변경할 수 있는 코드

전체코드

import React, { useState } from "react";
import "./style.css";
import { Provider, useSelector, useDispatch } from "react-redux";
import { createStore } from "redux";

function reducer(curState, action) {
  if (curState === undefined) {
    return {
      number: 1,
    };
  }
  const newState = { ...curState };
  
  if (action.type === 'PLUS'){
    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}>
          <Left1></Left1>
          <Right1></Right1>
        </Provider>
      </div>
    </div>
  );
}

function Left1(props) {
  return (
    <div>
      <h1>Left1</h1>
      <Left2></Left2>
    </div>
  );
}

function Left2(props) {
  return (
    <div>
      <h1>Left2</h1>
      <Left3></Left3>
    </div>
  );
}

function Left3(props) {
  function f(state) {
    return state.number;
  }
  const number = useSelector(f);
  //const number = useSelector((state) => {return state.number})
  return (
    <div>
      <h1>Left3 : {number}</h1>
    </div>
  );
}

function Right1(props) {
  return (
    <div>
      <h1>Right1</h1>
      <Right2></Right2>
    </div>
  );
}

function Right2(props) {
  return (
    <div>
      <h1>Right2</h1>
      <Right3></Right3>
    </div>
  );
}

function Right3(props) {
  const dispatch = useDispatch();
  return (
    <div>
      <h1>Right3</h1>
      <button onClick={() => {
        dispatch({ type: 'PLUS'})
      }}> + </button>
    </div>
  );
}

profile
주간 회고용 블로그입니다 (개발일지와 정보글은 티스토리에 작성합니다.)

0개의 댓글