hOC + redux

김영준·2020년 3월 30일
0

react

목록 보기
2/4
post-thumbnail

1. 제일 처음으로는 아래와 같이 액션타입, 액션생성함수, 리듀서 함수를 만들어준다.

src/modules/service.js 에서 액션 타입, 액션 함수를 설정한다.


const INSERT = "service/INSERT"; //액션함수의 타입 설정
const DELETE = "service/DELETE"; //액션함수의 타입 설정

let id = 2;
export const receiveService = data => {
  return {
    type: INSERT,
    payload: {
      name: data[data.length - 1].name,
      phone: data[data.length - 1].phone,
      id: id++
    }
  };
};
//receiveService 라는 액션함수를 만들었다. 
//type은 INSERT 이고, payload 로는 name ,phone, id 를 받게 된다.


export const deleteService = data => {
  return {
    type: DELETE,
    payload: data
  };
};
//deleteService 라는 액션 함수이다.

const initialstate = {
  data: [
    {
      name: "김영준",
      phone: "010-2277-7337",
      id: 1
    }
  ]
};
//초기 state 에는 다음과 같이 들어갈 것이다.

export default function serviceReducer(state = initialstate, action) {
  if (action.type === INSERT) {
    return { ...state, data: state.data.concat(action.payload) };
  } else if (action.type === DELETE) {
    return { ...state, data: state.data.action };
  } else return state;
}
// reducer 함수를 만든다.
// state는 initialState 가 들어가고, action이 들어간다.
// 1. TYPE이 INSERT 일 경우(receiveService 함수를 사용했을 때)에는 state의 data 에는 payload 로 받는 값을 concat 함수를 이용해서 추가하는 역할을 한다.
// 2. DELETE일 경우 에는 data가 null 로 표시되게 할 것이다. 

hOC(higher Order Component)를 만들어준다. , 위치 : src/hocs/withService.js

import React, { Component } from "react";
import { compose } from "recompose"; //recompose 를 사용한다.
import { connect } from "react-redux";
import { receiveService, deleteService } from "../modules/service";
//receiveService, deleteService 는 위에서 만든 액션함수이다.

export default ComposedComponent => {
  class withService extends Component {
    render() {
      return <ComposedComponent {...this.props} />;
    }
  }

  const mapStateToProps = state => ({
    service: state.service
  });

  const mapDispatchToProps = dispatch => ({
    serviceAction: {
      receiveService: service => dispatch(receiveService(service)),
      deleteService: () => dispatch(deleteService())
    }
  });

  return compose(connect(mapStateToProps, mapDispatchToProps))(withService);
};

참조
HOC 의 원리는, 파라미터로 컴포넌트를 받아오고, 함수 내부에서 새 컴포넌트를 만든 다음에 해당 컴포넌트 안에서 파라미터로 받아온 컴포넌트를 렌더링하는 것입니다.

src/container/serviceContainer.js

import React from "react";
import withService from "../hocs/withService";
import { compose } from "recompose";
import ServiceView from "../components/ServiceView";

const ServiceContainer = props => {
  return (
    <div>
      <ServiceView {...props} />
    </div>
  );
};

const wrappedService = compose(withService)(ServiceContainer);

export default wrappedService;

--> container파일에서 view component 를 감싸고 있는다.
compose 로 withService 를 serviceContainer 에 props로 넘겨받은 다음, 다시 props 로 ServiceView 로 넘겨준다.

src/components/ServiceView.js

import React, { useState } from "react";

const ServiceView = props => {
  console.log(props);
  const [name, setName] = useState(null);
  const [phone, setPhone] = useState(null);
  const _handlerName = e => {
    if (e.target.name === "name") {
      setName(e.target.value);
    } else {
      setPhone(e.target.value);
    }
  };
  const _addContact = e => {
    e.preventDefault();
    let profileData =
      props.service.data &&
      props.service.data.concat({
        name: name,
        phone: phone
      });
    let emptyData = { name: "김영준", phone: "010-2277-7337" };

    const _setValue =
      props.service.data === undefined ? emptyData : profileData;
    props.serviceAction.receiveService(_setValue);
  };
  const _deleteContact = e => {
    e.preventDefault();
    props.serviceAction.deleteService();
  };

  return (
    <div>
      {props.service && props.service.data && props.service.data ? (
        props.service.data.map((e, index) => (
          <div key={index}>
            <button>이름</button>: {e.name}
            <button>연락처</button> : {e.phone}
          </div>
        ))
      ) : (
        <div>값이 없습니다.</div>
      )}
      <hr />
      <form>
        <input onChange={_handlerName} name="name" />
        <input name="phone" onChange={_handlerName} />
        <button onClick={_addContact}>추가</button>
        <button onClick={_deleteContact}>삭제</button>
      </form>
    </div>
  );
};

export default ServiceView;


console.log 를 찍어보면 위와 같이 나오게 되는데, service 에는 state 의 값이 들어있고, serviceAction 에는 액션 함수가 들어있다.

이제 props로 받아온 withService에서 주는 값을 이용해서 redux 에 추가할 수 있다.

profile
프론트엔드 개발자 김영준 입니다. 디테일함을 키우고 있습니다

0개의 댓글