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.

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,
}

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


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: [],
  }
}

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)
}

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`)
    }
  }
}
Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.