안녕하세요 미루고 미루고 미루다 ( 끝 없는 배포의 연장으로 진행이 안된 상태로 이렇게 시간이... ㅜ ) 

 

최근 다시 데드라인이 다가오고 있기 때문에 급하게 관련 작업들을 진행을 하고 있습니다.

 

사실 FE쪽 디자인은 Antd를 사용하였는데 해당 포스팅은 다음 포스팅에 하도록 하고 ( 사용이 어렵지 않기 때문 )

 

Redux를 통한 전역 상태 관리에 대해서 우선 작성하게 되었습니다. Redux와 Hooks를 너무 오랜만에 사용하다보니 

 

기억이 너무 가물가물 했기 때문입니다

 

1차적으로는 모두의 룰인 Counter 입니다. Counter 작성 후 개발중인 페이지의 전역 상태 관리로 바로 넘어가겠습니다.

 

Store

React-Redux와 관련 @types 및 Redux의 내용들은 많은 검색을 통해 알수 있기 때문에 과감하게 생략 하겠습니다. 사용성 및 작성 순서대로만

 

import React from 'react';
import ReactDOM from 'react-dom';
import './index.css';
import { Provider } from 'react-redux';
import { createStore } from 'redux';
import App from './App';
import rootReducer from './redux';


const store = createStore(rootReducer);

ReactDOM.render(
  <React.StrictMode>
    <Provider store={store}>
        <App />
    </Provider>
  </React.StrictMode>,
  document.getElementById('root')
);

1차적으로 react-redux의 Provider를 받아와서 App 을 통해 전달 합니다.

* 한 개의 프로젝트는 단 하나의 스토어만 가질수 있으며 스토어 안에는 애플리케이션의 현재 상태 및 리듀서가 있습니다.

Store에 있는 상태값을 가져와서 사용하는 컴포넌트라면 아래의 순서를 거치게 됩니다.

 

컴포넌트 ( 1. 스토어를 통해 상태 값을 받아옴 ) 

컴포넌트 ( 2. 받아온 상태값으로 렌더 ) 

컴포넌트 ( 3. 상태 변경을 위해서 액션 디스패치 -> 스토어가 변경됨 )

컴포넌트 ( 4. 스토어의 상태가 변경되면서 다시 컴포넌트를 재 렌더링 )

 

액션 : 상태 변화시 발생하는 것

액션 생성 : 액션을 만들어서 상태 변화시 사용

리듀서 : 변화를 일으킴 액션을 파라미터로 받아서 새로운 상태를 만든 후 반환 

디스패치 : 액션을 발생 시킴 디스패치가 호출시 스토어가 리듀서 함수를 실행시켜서 새로운 상태를 만듬

 

여러가지의 상태를 사용하기 위해서는 리듀서를 여러개 사용하여야 하기 때문에 Combine 함수를 통해 rootReducer를 만든 후 해당 리듀서를 Store 에 전달합니다.

 

( rootReducer )

import { combineReducers } from 'redux';

const rootReducer = combineReducers({

});

export default rootReducer;

( CounterReducer )

const INCREASE = 'counter/INCREASE';
const DECREASE = 'counter/DECREASAE';


interface counterAction {
  type:string;
}
export const increase = () =>({type:INCREASE});
export const decrease = () =>({type:DECREASE});

const initialState = {
  number : 55
}

function counter(state = initialState,action:counterAction){
  switch(action.type){
    case INCREASE:
      return{
        number:state.number + 1
      };
    case DECREASE:
      return{
        number:state.number -1
      };
    default:
      return state;
  }
}

export default counter;

( App 에서 hooks를 통해 state를 selector ) 

import React from 'react';
import './App.css';
import ReduxComponent from './ReduxComponent'
import { useSelector } from 'react-redux';
import { increase, decrease } from './redux/counter';
function App() {
  const number = useSelector((state:any) => state.counter.number);

  return (
    <div className="App">
          Test App 
          <ReduxComponent number={number}></ReduxComponent>
    </div>
  );
}

export default App;

( ReduxComponent )

import React from 'react';

const ReduxComponent:React.FunctionComponent<any> = ({number,onIncrease,onDecrease}) => {
  
  return (
    <div>
      <h1>{number}</h1>
        <div>
          <button onClick={onIncrease} >+1</button>
          <button onClick={onDecrease} >-1</button>
        </div>
    </div>
    
  );
}

export default ReduxComponent;

 결과

이제 동작하기 위한 Dispatch

import React from 'react';
import './App.css';
import ReduxComponent from './ReduxComponent'
import { useSelector , useDispatch } from 'react-redux';
import { increase, decrease } from './redux/counter';
function App() {
  const number = useSelector((state:any) => state.counter.number);
  const dispatch = useDispatch();
  return (
    <div className="App">
          Test App 
          <ReduxComponent number={number} 
          onIncrease={()=> dispatch(increase)}
          onDecrease={()=> dispatch(decrease)}
          ></ReduxComponent>
    </div>
  );
}

export default App;

실행결과

Error: Actions must be plain objects. Instead, the actual type was: 'function'. You may need to add middleware to your store setup to handle dispatching other values, such as 'redux-thunk' to handle dispatching functions.

 

액션은 plain object 여야 한다 -> increase, decrease 액션 디버깅 

 

딱 봐도 객체가 아니라 함수로 리턴 되는 것 처럼 보이네요

       onIncrease={()=> dispatch(increase())}
       onDecrease={()=> dispatch(decrease())}

 

오타였네요 여기서 실행했어야; 

수정하니 정상적으로 잘되네용 ~ hooks 기억 되살리기 끝 다음 포스팅에 작업중인 자동화 플랫폼에 적용 하도록 하겠습니다.

 

+ Recent posts