Dev/Web

[React] Store Library - Redux

더움바다 2023. 8. 22. 01:32

오늘은 redux에 대해 알아보겠습니다.

https://www.npmjs.com/package/redux

https://ko.redux.js.org/

 

redux

Predictable state container for JavaScript apps. Latest version: 4.2.1, last published: 7 months ago. Start using redux in your project by running `npm i redux`. There are 17342 other projects in the npm registry using redux.

www.npmjs.com

 

Redux - 자바스크립트 앱을 위한 예측 가능한 상태 컨테이너. | Redux

자바스크립트 앱을 위한 예측 가능한 상태 컨테이너.

ko.redux.js.org

 

Redux는 심플하게 글로벌 상태 관리 라이브러리입니다.

React의 경우 페이지 내의 상태를 관리하는것엔 용이하지만 전역적인 상태관리를 할 경우에 복잡한 부분이 있습니다.

https://react.dev/reference/react/useContext

// App.js
import {DefaultContext, useContextValue, useDefaultContext} from "./context";

function Button() {
  const { increment, value, decrement } = useDefaultContext();

  return (
    <div>
      <button onClick={increment}>
        increment
      </button>
      {value}
      <button onClick={decrement}>
        decrement
      </button>
    </div>
  )
}

function App() {
  const providerValue = useContextValue();

  return (
    <DefaultContext.Provider value={providerValue}>
      <Button />
    </DefaultContext.Provider>
  );
}

export default App;


// context.js
import {createContext, useCallback, useContext, useState} from "react";

export const DefaultContext = createContext();

export function useContextValue() {
  const [value, setValue] = useState(0);

  const increment = useCallback(() => {
    setValue(prevState => prevState + 1);
  }, []);

  const decrement = useCallback(() => {
    setValue(prevState => prevState - 1);
  }, []);

  return {
    increment,
    value,
    decrement
  }
}

export function useDefaultContext() {
  return useContext(DefaultContext);
}

 

그렇지만 Redux를 사용하면 상대적으로 더 깔끔하게 관리할수 있습니다.

출처: https://ko.redux.js.org/

// App.js
import {DefaultContext, useContextValue, useDefaultContext} from "./context";
import { store } from "./store";
import {useState} from "react";

function Button() {
  const [_, forceUpdate] = useState({});

  function increment() {
    store.dispatch({ type: 'INCREMENT' });
    console.log('state', store.getState());
    // forceUpdate를 해주지 않을 경우 re-render가 발생하지 않음
    forceUpdate({});
  }

  function decrement() {
    store.dispatch({ type: 'DECREMENT' })
    console.log('state', store.getState());
    // forceUpdate를 해주지 않을 경우 re-render가 발생하지 않음
    forceUpdate({});
  }

  return (
    <div>
      <button onClick={increment}>
        increment
      </button>
      {store.getState()}
      <button onClick={decrement}>
        decrement
      </button>
    </div>
  )
}

function App() {
  const providerValue = useContextValue();

  return (
    <DefaultContext.Provider value={providerValue}>
      <Button />
    </DefaultContext.Provider>
  );
}

export default App;

// store.js
import { createStore } from 'redux'

function counter(state = 0, action) {
  switch (action.type) {
    case 'INCREMENT':
      return state + 1
    case 'DECREMENT':
      return state - 1
    default:
      return state
  }
}

export const store = createStore(counter)

다만 여기선 pure redux를 사용했기에 rendering과 연동되어 있진 않습니다.

연동하고 싶으시다면 react-redux를 사용해 store가 업데이트될시 실시간으로 re-rendering하게 해줘야 합니다.

다음 글에서는 react-redux에 대해 알아보겠습니다.

 

긴글 봐주셔서 감사합니다.

'Dev > Web' 카테고리의 다른 글

[JavaScript] Falsy Value  (0) 2023.11.09
[React] Hook의 이해-2 (useMemo, useCallback, useRef)  (0) 2023.04.26
[React] Hook의 이해-1 (useState, useEffect)  (2) 2023.04.18