Bereaksi array proptype dengan bentuk

244

Apakah ada cara bawaan untuk menggunakan proptypes untuk memastikan bahwa array objek yang diteruskan ke komponen sebenarnya adalah array objek dengan bentuk tertentu?

Mungkin kira-kira seperti ini?

annotationRanges: PropTypes.array(PropTypes.shape({
    start: PropTypes.number.isRequired,
    end: PropTypes.number.isRequired,
})),

Apakah saya melewatkan sesuatu yang sangat jelas di sini? Sepertinya ini akan sangat dicari.

majorBummer
sumber

Jawaban:

370

Anda dapat menggunakan React.PropTypes.shape()sebagai argumen untuk React.PropTypes.arrayOf():

// an array of a particular shape.
ReactComponent.propTypes = {
   arrayWithShape: React.PropTypes.arrayOf(React.PropTypes.shape({
     color: React.PropTypes.string.isRequired,
     fontSize: React.PropTypes.number.isRequired,
   })).isRequired,
}

Lihat bagian Validasi Prop dari dokumentasi.

MEMPERBARUI

Pada react v15.5, penggunaan React.PropTypessudah tidak digunakan lagi dan paket mandiri prop-typesharus digunakan sebagai gantinya:

// an array of a particular shape.
import PropTypes from 'prop-types'; // ES6 
var PropTypes = require('prop-types'); // ES5 with npm
ReactComponent.propTypes = {
   arrayWithShape: PropTypes.arrayOf(PropTypes.shape({
     color: PropTypes.string.isRequired,
     fontSize: PropTypes.number.isRequired,
   })).isRequired,
}
Pierre Criulanscy
sumber
17
Ada baiknya menunjukkan penggunaan .isRequiredpada setiap properti React.PropTypes.shape. Saya tiba di sini karena saya salah diasumsikan bahwa dengan menggunakan .isRequiredpada React.PropTypes.arrayOf, saya tidak membutuhkannya dalam. Untuk mencapai validasi cakupan penuh, saya benar-benar akhirnya menerapkannya juga secara langsung React.PropTypes.shape.
gfullam
1
Ya, saya melakukan hal yang sama persis dari Anda, tetapi jauh lebih kuat untuk memiliki kemungkinan untuk hanya menandai sesuai kebutuhan tombol yang Anda inginkan. Omong kosong selalu lebih baik daripada implisit bagi saya.
Pierre Criulanscy
Contoh ini tidak gagal validasi dengan benar untuk saya. Jika if arrayWithShapeadalah [] (array kosong) Tidak gagal. jika arrayWithShape{} (sebuah objek) itu gagal. If arrayWithShape is [{dumb: 'something'}](array tanpa alat peraga yang benar) gagal. Saya perlu gagal validasi jika arrayWithShapearray kosong. Saya hanya ingin itu lulus jika itu adalah array kosong dengan objek yang memiliki alat peraga colordan fontsize. Apa yang saya lewatkan?
sdc
50

Ya, Anda harus menggunakan PropTypes.arrayOfalih-alih PropTypes.arraydalam kode, Anda dapat melakukan sesuatu seperti ini:

import PropTypes from 'prop-types';

MyComponent.propTypes = {
  annotationRanges: PropTypes.arrayOf(
    PropTypes.shape({
      start: PropTypes.string.isRequired,
      end: PropTypes.number.isRequired
    }).isRequired
  ).isRequired
}

Juga untuk detail lebih lanjut tentang proptypes , kunjungi Typechecking With PropTypes di sini

Alireza
sumber
3
Apa alasan untuk menambahkan .isRequired ke objek PropTypes.shape?
makovkastar
@makovkastar Karena tanpa itu, [undefined]akan melewati validasi
user123
6

Ada impor steno ES6, Anda dapat referensi. Lebih mudah dibaca dan mudah diketik.

import React, { Component } from 'react';
import { arrayOf, shape, number } from 'prop-types';

class ExampleComponent extends Component {
  static propTypes = {
    annotationRanges: arrayOf(shape({
      start: number,
      end: number,
    })).isRequired,
  }

  static defaultProps = {
     annotationRanges: [],
  }
}
Moewiz
sumber
1
Harap tinjau Bagaimana cara menulis jawaban yang baik . Jawaban hanya kode tidak disarankan karena tidak menjelaskan bagaimana mereka menyelesaikan masalah dalam pertanyaan. Anda harus memperbarui jawaban Anda untuk menjelaskan apa yang dilakukannya dan bagaimana meningkatkannya pada jawaban yang dipilih yang sudah dimiliki pertanyaan ini.
FluffyKitten
1

Jika saya harus mendefinisikan proptypes yang sama untuk bentuk tertentu beberapa kali, saya suka abstrak itu ke file proptypes sehingga jika bentuk objek berubah, saya hanya perlu mengubah kode di satu tempat. Ini membantu mengeringkan basis kode sedikit.

Contoh:

// Inside my proptypes.js file
import PT from 'prop-types';

export const product = {
  id: PT.number.isRequired,
  title: PT.string.isRequired,
  sku: PT.string.isRequired,
  description: PT.string.isRequired,
};


// Inside my component file
import PT from 'prop-types';
import { product } from './proptypes;


List.propTypes = {
  productList: PT.arrayOf(product)
}
Yo Wakita
sumber
0

Ini adalah solusi saya untuk melindungi dari array kosong juga:

import React, { Component } from 'react';
import { arrayOf, shape, string, number } from 'prop-types';

ReactComponent.propTypes = {
  arrayWithShape: (props, propName, componentName) => {
    const arrayWithShape = props[propName]
    PropTypes.checkPropTypes({ arrayWithShape:
        arrayOf(
          shape({
            color: string.isRequired,
            fontSize: number.isRequired,
          }).isRequired
      ).isRequired
    }, {arrayWithShape}, 'prop', componentName);
    if(arrayWithShape.length < 1){
      return new Error(`${propName} is empty`)
    }
  }
}
sdc
sumber