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

[React] 컴포넌트에 스타일을 적용해보자 ③ Checkbox

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

2020/09/29 - [Web프론트엔드/리액트] - [React] 리액트 기초 관련 글 정리 (개발환경, 데이터, 컴포넌트 등)

2020/10/06 - [Web프론트엔드/리액트] - [React] 재활용 가능한 기본적인 Input 컴포넌트

2020/10/06 - [Web프론트엔드/리액트] - [React] 테스트 도구인 스토리북(storybook)을 사용해보자

2020/10/06 - [Web프론트엔드/리액트] - [React] 스토리북에 다양한 확장 도구(Addon) 추가

2020/10/07 - [Web프론트엔드/리액트] - [React] 컴포넌트에 스타일을 적용해보자 ① Text

2020/10/08 - [Web프론트엔드/리액트] - [React] 컴포넌트에 스타일을 적용해보자 ② Button


 스타일 컴포넌트의 세 번째는 체크박스입니다. Input 컴포넌트의 type을 checkbox로 바꾼 정도라 Input이라고도 할 수 있습니다. 하지만 이미 많이 다룬 내용이라 이번에는 체크박스를 만들어 보도록 하겠습니다. 바로 가보시죠!

 

// ..\test_project\src\components\Checkbox.jsx

import React, { PureComponent } from "react";
import PropTypes from "prop-types";
import withStyles, { css } from "../styles/withStyles";

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

    this.state = {
      checked: props.checked, // 상위 프로퍼티로 초기화
    };

    // 콜백 함수 바인딩
    this.setRef = this.setRef.bind(this);
    this.handleClick = this.handleClick.bind(this);
  }

  // ref 프로퍼티 연결
  setRef(ref) {
    this.ref = ref;
  }

  // 클릭 이벤트
  handleClick(e) {
    const { name, onChange } = this.props;

    console.log(
      `handleClick() name : ${name} , e.target.checked : ${e.target.checked}`
    );

    // 변경된 스테이트 값
    this.setState({ checked: e.target.checked });

    // 상위 컴포넌트 콜백 함수 실행
    onChange(name, e.target.checked);
  }

  // 컴포넌트 마운트
  componentDidMount() {
    // 포커스 맞추기
    if (this.props.autoFocus) {
      this.ref.focus();
    }
  }

  render() {
    // 프로퍼티 받아서 화면 출력
    const { label, children, styles, errorMessage } = this.props;
    console.log(`this.state.checked : ${this.state.checked}`);
    return (
      <label>
        {label}
        <div>
          <input
            id={`input_${name}`}
            type="checkbox"
            ref={this.setRef}
            checked={this.state.checked && "checked"}
            onClick={this.handleClick}
          />
          {children}
        </div>
        {errorMessage && (
          <div>
            <span {...css(styles.errorText)}>{errorMessage}</span>
          </div>
        )}
      </label>
    );
  }
}

// name 프로퍼티 필수
Checkbox.propTypes = {
  name: PropTypes.string.isRequired,
  autoFocus: PropTypes.bool,
  checked: PropTypes.bool,
  onChange: PropTypes.func,
};

// 디폴트 프로퍼티 값
Checkbox.defaultProps = {
  autoFocus: false,
  checked: false,
  onChange: () => {},
};

// withStyles()함수를 사용해 defaultStyles.js 내용으로 매칭
export default withStyles(({ color, size }) => ({
  errorText: {
    fontSize: size.medium,
    color: color.error,
  },
}))(Checkbox);

 

 지난 포스팅인 "재활용 가능한 기본적인 Input 컴포넌트"의 뼈대에, type를 checkbox로 하고 value값을 checked로 변경한 정도입니다. 나머지는 약간의 스타일을 적용했을 뿐입니다. 이제 스토리북에 넣어 확인해보겠습니다.

 

// ..\test_project\src\stories\Story_TestCheckbox.jsx

import React from "react";
import { storiesOf } from "@storybook/react";
import { action } from "@storybook/addon-actions";
import Checkbox from "../components/Checkbox";
import Text from "../components/Text";

storiesOf("Test Checkbox", module)
  .addWithJSX("base", () => <Checkbox name="check" />)
  .addWithJSX("children", () => (
    <Checkbox name="check">
      <Text>코로나와 헤어집니다</Text>
    </Checkbox>
  ))
  .addWithJSX("label", () => (
    <Checkbox name="check" label="결별">
      <Text>코로나와 헤어집니다</Text>
    </Checkbox>
  ))
  .addWithJSX("checked", () => (
    <Checkbox name="check" label="결별" checked>
      <Text>코로나와 헤어집니다</Text>
    </Checkbox>
  ))
  .addWithJSX("errorMessage", () => (
    <Checkbox name="check" label="결별" errorMessage="무조건 체크해야 합니다!">
      <Text>코로나와 헤어집니다</Text>
    </Checkbox>
  ))
  .addWithJSX("onChange", () => (
    <Checkbox name="check" onChange={action("onChange 이벤트")}>
      <Text>코로나와 헤어집니다</Text>
    </Checkbox>
  ));

 

 이번에는 Text 스타일 컴포넌트도 함께 사용해봤습니다. <Checkbox>부모 컴포넌트이고 <Text>자식 컴포넌트입니다. 스토리북에서 체크박스를 클릭하면 잘 작동하는 것이 보입니다. 아래 화면처럼 클릭 이벤트 로그도 확인 가능합니다.

 

Checkbox 클릭 액션

 

 오늘은 여기까지 입니다. 스타일 컴포넌트 관련 글이 벌써 3번째군요! 이제 감이 잡히실 거라 믿습니다^^

 

참 쉽죠?


2020/10/08 - [Web프론트엔드/리액트] - [React] 컴포넌트에 스타일을 적용해보자 ④ media 속성

댓글