eslint react/prop-types の対応(プロパティがオブジェクトの場合)

やりたい事

  • eslint-config-airbnbに準拠したReactコンポーネントの実装
  • プロパティにはオブジェクトを引数として渡す

How to build a movie search app using React Hooksからコードを引用

import React from 'react';

const DEFAULT_PLACEHOLDER_IMAGE = 'https://m.media-amazon.com/images/M/MV5BMTczNTI2ODUwOF5BMl5BanBnXkFtZTcwMTU0NTIzMw@@._V1_SX300.jpg';

const Movie = ({ movie }) => {
  const { Poster } = movie;
  const imgPath = Poster === 'N/A'
    ? DEFAULT_PLACEHOLDER_IMAGE : Poster;

  return (
    <div className="movie">
      <h2>{movie.Title}</h2>
      <div>
        <img
          width="200"
          alt={`The Movie title: ${movie.Title}`}
          src={imgPath}
        />
      </div>
      <p>
        (
        {movie.Year}
        )
      </p>
    </div>
  );
};

export default Movie;

上記のコードはeslint(react/prop-types)が発生する。 これはコンポーネントに渡されるプロパティの値が未定義のため発生しているので、 プロパティのmovieを定義することで解決する。

PropTypesによる型定義

プロパティ値のmovieはオブジェクトのため、PropTypes.shapeを使用して型定義を行う。

参考 Qiita - ReactのPropTypes Validator

import React from 'react';
+import PropTypes from 'prop-types';

const DEFAULT_PLACEHOLDER_IMAGE = 'https://m.media-amazon.com/images/M/MV5BMTczNTI2ODUwOF5BMl5BanBnXkFtZTcwMTU0NTIzMw@@._V1_SX300.jpg';

const Movie = ({ movie }) => {
  const { Poster } = movie;
  const imgPath = Poster === 'N/A'
    ? DEFAULT_PLACEHOLDER_IMAGE : Poster;

  return (
    <div className="movie">
      <h2>{movie.Title}</h2>
      <div>
        <img
          width="200"
          alt={`The Movie title: ${movie.Title}`}
          src={imgPath}
        />
      </div>
      <p>
        (
        {movie.Year}
        )
      </p>
    </div>
  );
};

+Movie.propTypes = {
+  movie: PropTypes.shape({
+    Poster: PropTypes.string.isRequired,
+    Title: PropTypes.string.isRequired,
+    Year: PropTypes.string.isRequired,
+  }).isRequired,
+};

export default Movie;