티스토리 뷰

기존 리액트 코드에서 state 객체 안에 input의 값을 추가 할 때 onChange를 통해 값이 생성되면 state안에 키값과 밸류값을 넣도록 만들어 두었었다.



// ex
const inputHandler = e => {
    const { namevalue } = e.target;
    setState(...state, ...{ [name]: value });
  };


이런 상황에서 리덕스를 사용할 경우 정의되지 않은 state의 키와 밸류를 추가 할 수 있을지와  의문이 들었다.

문제는 리듀서에서 발생을 했다. 리듀서는 action과 state만을 인자로 받기 때문에 [name]의 값을 가져올 수 없었다.

이를 해결하려면 action자체를 스프레드(...)하면 되지만 이경우에 action안에 있는 type의 값까지 같이 state에 반영이 된다.

돌아는 가겠지만 안티패턴이란느 생각을 지울 수 없었다.



const CHANGE_INPUT = "carInfo/CHANGE_INPUT";

export const changeInput = (namevalue=> ({
  type: CHANGE_INPUT,
  [name]: value
});

const initialState = {
  car_num: "",
  car_own_name: ""
};

export default function carInfo(state = initialStateaction) {
  switch (action.type) {
    case CHANGE_INPUT:
      console.log(action);
      console.log(state);
      return {
        ...state,
        ...action
    default:
      return state;
  }
}


그에 따라  각 input마다 함수를 생성하는 것은 너무 비효율 적이므로 state를 정의하고 action에 값이 없으면 state의 값을 넣음으로써 상태관리를 하는 것으로 결정했다.



const CHANGE_INPUT = "carInfo/CHANGE_INPUT";

export const changeInput = (namevalue=> ({
  type: CHANGE_INPUT,
  [name]: value
});

const initialState = {
  car_num: "",
  car_own_name: ""
};

export default function carInfo(state = initialStateaction) {
  switch (action.type) {
    case CHANGE_INPUT:
      return {
        ...state,
        ...{
          car_num: action.car_num || state.car_num,
          car_own_name: action.car_own_name || state.car_own_name
        }
      };
    default:
      return state;
  }
}


아래는 react 코드이다



import React, { useEffect } from "react";
import { changeInput } from "../store/modules/carInfo";
import { connect } from "react-redux";

const CarInfo = ({ car_numcar_own_namechangeInput }) => {
  const inputHandler = e => {
    const { namevalue } = e.target;
    changeInput(namevalue);
  };

  return (
    <div>
      <div>
        <p className="input_title">차량번호</p>
        <input
          type="text"
          name="car_num"
          value={car_num}
          onChange={inputHandler}
        />
      </div>
      <div className="input_wrap">
        <p className="input_title">소유주이름</p>
        <input
          type="text"
          name="car_own_name"
          value={car_own_name}
          onChange={inputHandler}
        />
      </div>
    </div>
  );
};

const mapStateToProps = state => {
  return {
    car_num: state.carInfo.car_num,
    car_own_name: state.carInfo.car_own_name
  };
};

const mapDispatchToProps = dispatch => {
  return {
    changeInput: (namevalue=> dispatch(changeInput(namevalue))
  };
};

const CarInfoContainer = connect(
  mapStateToProps,
  mapDispatchToProps
)(CarInfo);

export default CarInfoContainer;


반응형
댓글