본문 바로가기
웹 프론트엔드/React 리액트 (기초)

[React] 리덕스(redux) 기능으로 데이터 관리하기 ⑤ 커넥트

by 지구인한군 2020. 10. 27.

 지난 리덕스 세 번째 포스팅에서 코드 분리를 했습니다. 크게 액션과 리듀서로 나눴는데, 이번에는 커넥트(connect)를 사용하여 화면(view) 컴포넌트와 데이터(container) 컴포넌트로 분리해보겠습니다. 쉽게 말씀드리면 화면에 뿌려주는 재사용 가능한 컴포넌트에 리덕스 스토어 데이터를 연결하는 것입니다. 지난 시간에 했던 소스코드에서 분리하겠습니다.

 

2020/10/27 - [Web프론트엔드/리액트] - [React] 리덕스(redux) 기능으로 데이터 관리하기 ④ 해시맵

 

먼저 views폴더 안에 화면 컴포넌트를 만들겠습니다. 유저 데이터인 id, pass, name 그리고 수정 버튼입니다.

 

// ..\test_project\src\components\views\UserDataView.jsx

import React, { PureComponent } from "react";
import PropTypes from "prop-types";
import Text from "../Text";
import Button from "../Button";

class UserDataView extends PureComponent {
  render() {
    const { id, data, editUser } = this.props;
    return (
      <div id={id}>
        <Text>KEY : {id}</Text>
        <br />
        <Text>ID : {data.uid}</Text>
        <br />
        <Text>PASS : {data.pass}</Text>
        <br />
        <Text>NAME : {data.name}</Text>
        <br />
        <Button
          name={data.uid}
          onClick={() => editUser(data.key, "넌 이미 죽어 있다_" + data.uid)}
        >
          수정
        </Button>
        <br />
      </div>
    );
  }
}

UserDataView.PropTypes = {
  id: PropTypes.number,
  data: PropTypes.shape({
    uid: PropTypes.string,
    pass: PropTypes.string,
    name: PropTypes.string,
  }),
};

export default UserDataView;

 

너무 간단하죠? 중요한 부분은 프로퍼티로 받는 id(key) 값, data(유저 데이터), editUser(액션)입니다. 그럼 이제 containers폴더 안에 데이터(컨테이너) 컴포넌트를 만들고 connect()를 사용하여 화면 컴포넌트와 연결해보겠습니다.

 

// ..\test_project\src\components\containers\UserDataContainer.jsx

import { connect } from "react-redux";
import UserDataView from "../views/UserDataView";
import { editUser } from "../actions/userActions";

// 데이터 연결
const mapStateToProps = (state, props) => {
  return {
    data: state.userReducer.objs[props.id],
  };
};

// 액션 연결
const mapDispatchToProps = {
  editUser,
};

export default connect(mapStateToProps, mapDispatchToProps)(UserDataView);

 

이것도 간단하죠? mapStateToProps가 데이터 연결, mapDispatchToProps가 액션 연결입니다. connect() 함수는 하이오더 컴포넌트(HoC)로 UserDataView를 옆에 붙이면 됩니다. 마지막으로 이 컴포넌트를 사용하면 끝입니다. 

 

2020/10/09 - [Web프론트엔드/리액트] - [React] 하이오더(HoC) 기능으로 컴포넌트 확장하기 ①

2020/10/12 - [Web프론트엔드/리액트] - [React] 하이오더(HoC) 기능으로 컴포넌트 확장하기 ②

 

// ..\test_project\src\components\UserDataRedux_new.jsx

import React, { PureComponent } from "react";
import { Provider } from "react-redux";
import reduxCreateStore from "./reduxCreateStore";
import { setUser, addUser } from "./actions/userActions";
import Button from "./Button";
import UserDataContainer from "./containers/UserDataContainer";

class UserDataRedux extends PureComponent {
  constructor(props) {
    super(props);

    this.state = {
      count: 20,
    };

    // 콜백 함수 바인딩
    this.addUser = this.addUser.bind(this);

    // 커스터마이징 함수로 스토어 생성
    this.store = reduxCreateStore();

    // 유저 데이터 세팅
    this.store.dispatch(
      setUser([
        {
          uid: "corona",
          pass: "dead4444",
          name: "넌왜왔니",
        },
        {
          uid: "corona19",
          pass: "ojimasio",
          name: "잘가세요",
        },
      ])
    );
  }

  // 유저 데이터 추가
  addUser() {
    this.store.dispatch(
      addUser([
        {
          uid: "corona" + this.state.count,
          pass: "nothing" + this.state.count,
          name: "없습니다" + this.state.count,
        },
      ])
    );
    this.setState({ count: this.state.count + 1 });
  }

  render() {
    // 유저 리듀서
    const { userReducer } = this.store.getState();
    // 키와 객체 데이터
    const { keys, objs } = userReducer;
    // 키에 맞는 유저 데이터
    const userData = keys.map((key) => objs[key]);
    // 프로바이더를 사용하여 자식에게 데이터 전달
    return (
      <Provider store={this.store}>
        {userData.map((item) => (
          <React.Fragment key={item.key}>
            <UserDataContainer id={item.key} />
          </React.Fragment>
        ))}
        <br />
        <Button name="add" onClick={this.addUser}>
          추가
        </Button>
      </Provider>
    );
  }
}

export default UserDataRedux;

 

 지난 시간에 했던 로직과 같습니다. 단지 render() 함수 안에 UserDataContainer 컴포넌트가 추가된 것뿐입니다. 코드가 훨씬 간결해졌으며 화면과 데이터 컴포넌트가 나눠져 있어 유지보수도 용이합니다. 또한 화면 컴포넌트는 의존성이 낮아 재사용하기에도 편리합니다.  이렇듯 connect() 기능은 리액트의 강점인 코드의 재활용을 도와줍니다.

 

 이번 포스팅이 리덕스 기초 관련 내용으로는 마지막 포스팅이 될 거 같습니다. 이때까지 배운 내용과 커넥트 기능을 알면 실무에서도 충분히 사용 가능하리라 생각합니다. 추후 리덕스 고급 기능인 미들웨어나 redux-thunk 등의 사용법도 다룰 예정?입니다. 다섯 번이나 되는 긴 포스팅 읽어주셔서 감사하고 고생하셨습니다. 개발자 여러분~ 사랑존경합니다!

 

오늘도 참 쉽죠?

댓글