Make it to make it

いろいろ作ってアウトプットするブログ

PropTypesによるバリデーション

JavaScriptにはBoolean, Null, Undefined, Number, String, Symbol, Objectの7種類のデータ・タイプが存在する。 それらの型をハンドリングする際にFlowとかTypeScriptなどのツールが導入されているわけだが、Reactのプロジェクトでそこまで導入するのが面倒で手間なとき、PropTypesによるバリデーションが便利。 reactjs.org

以下にPropTypesの使用例を示す。

import React from 'react';
import ReactDOM from 'react-dom';
import PropTypes from 'prop-types';

class Badge extends React.Component {
  render() {
    const { authed, style, name, handle, img, addFriend } = this.props;

    if (authed !== true) {
      return <p>You need to log in.</p>;
    }

    return (
      <div style={style}>
        <img
          src={img}
          style={{ borderRadius: '50%' }}
          alt=""
          width="200"
          height="200"
        />
        <h1 style={{ margin: '15px 0 5px', fontSize: '2rem' }}>{name}</h1>
        <h3 style={{ margin: '5px 0', fontSize: '1rem' }}>@{handle}</h3>
        <button
          type="button"
          onClick={addFriend}
          style={{ margin: '10px 0 0' }}
        >
          Add Friend
        </button>
      </div>
    );
  }
}

Badge.propTypes = {
  authed: PropTypes.bool,
  style: PropTypes.objectOf(
    PropTypes.oneOfType([PropTypes.number, PropTypes.string])
  ),
  name: PropTypes.string.isRequired,
  handle(props, propName, component) {
    if (props[propName] === '' || !/^([^\s]|\w+)$/.test(props[propName])) {
      return new Error(`Invalid prop passed to ${component}`);
    }
  },
  img(props, propName, component) {
    if (
      props[propName] === '' ||
      // eslint-disable-next-line no-useless-escape
      !/^(?:http(s)?:\/\/)?[\w.-]+(?:\.[\w\.-]+)+[\w\-\._~:/?#[\]@!\$&'\(\)\*\+,;=.]+$/.test(
        props[propName]
      )
    ) {
      return new Error(`Invalid prop passed to ${component}`);
    }
  },
  addFriend: PropTypes.func,
};

ReactDOM.render(
  <Badge
    name="Random Dude"
    handle="RandomDude"
    img="https://i.pravatar.cc/600"
    authed
    style={{
      width: 300,
      margin: '0 auto',
      border: '3px solid #000',
      padding: 20,
      borderRadius: 3,
      display: 'flex',
      flexDirection: 'column',
      alignItems: 'center',
    }}
    addFriend={() => alert('Added!')}
  />,
  document.getElementById('app')
);

PropTypesのビルトインメソッドの他にも、上記のようにregexなどでのCustom validationも可能になっている。 下記のポストも参考になるので目を通しておくとよい。

blog.bitsrc.io