ตอบสนองอาร์เรย์ proptype ที่มีรูปร่าง


245

มีวิธีการใช้ proptypes ในตัวเพื่อให้แน่ใจว่าอาร์เรย์ของวัตถุที่ถูกส่งผ่านไปยังองค์ประกอบเป็นอาร์เรย์ของวัตถุที่มีรูปร่างเฉพาะหรือไม่?

อาจจะเป็นเช่นนี้?

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

ฉันขาดสิ่งที่เห็นได้ชัดที่สุดที่นี่หรือไม่? ดูเหมือนว่าสิ่งนี้จะเป็นที่ต้องการอย่างสูง

คำตอบ:


371

คุณสามารถใช้React.PropTypes.shape()เป็นอาร์กิวเมนต์เพื่อ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,
}

ดูส่วนการตรวจสอบความถูกต้องของเอกสารประกอบ

UPDATE

ตั้งแต่การreact v15.5ใช้React.PropTypesเลิกใช้แล้วและprop-typesควรใช้แพ็คเกจแบบสแตนด์อโลนแทน:

// 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
มันคุ้มค่าที่ชี้ให้เห็นการใช้งานเกี่ยวกับทรัพย์สินของแต่ละ.isRequired React.PropTypes.shapeฉันมาที่นี่เพราะฉันคิดว่าผิดโดยใช้.isRequiredบนReact.PropTypes.arrayOfฉันไม่ต้องการมัน เพื่อให้เกิดการตรวจสอบความครอบคลุมทั้งหมดฉันได้ลงทะเบียนโดยตรงกับมันReact.PropTypes.shapeเช่นกัน
gfullam

1
ใช่ฉันกำลังทำสิ่งเดียวกันกับคุณ แต่มันมีประสิทธิภาพมากกว่าที่จะมีความเป็นไปได้ที่จะตั้งค่าสถานะเฉพาะคีย์ที่คุณต้องการเท่านั้น อย่างชัดเจนดีกว่าเสมอสำหรับฉันโดยวิธี
Pierre Criulanscy

ตัวอย่างนี้ไม่ผ่านการตรวจสอบอย่างถูกต้องสำหรับฉัน ถ้า if arrayWithShapeคือ [] (อาร์เรย์ว่าง) มันจะไม่ล้มเหลว ถ้าarrayWithShapeเป็น {} (วัตถุ) มันล้มเหลว ถ้า arrayWithShape เป็น[{dumb: 'something'}](อาร์เรย์ที่ไม่มีอุปกรณ์ประกอบฉากถูกต้อง) มันล้มเหลว ฉันต้องการมันล้มเหลวในการตรวจสอบถ้าarrayWithShapeเป็นอาร์เรย์ที่ว่างเปล่า ฉันเพียงต้องการให้ผ่านถ้ามันเป็นอาร์เรย์ที่ว่างเปล่าที่ไม่ได้กับวัตถุที่มีอุปกรณ์ประกอบฉากและcolor fontsizeฉันพลาดอะไรไป
sdc

50

ใช่คุณต้องใช้PropTypes.arrayOfแทนPropTypes.arrayรหัสคุณสามารถทำสิ่งนี้:

import PropTypes from 'prop-types';

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

นอกจากนี้สำหรับรายละเอียดเพิ่มเติมเกี่ยวกับproptypesให้ไปที่Typechecking With PropTypes ที่นี่


3
เหตุผลในการเพิ่ม. isRequired ให้กับวัตถุ PropTypes.shape คืออะไร
makovkastar

@makovkastar เพราะไม่มีมัน[undefined]จะผ่านการตรวจสอบ
user123


6

มีการนำเข้าชวเลข ES6 คุณสามารถอ้างอิงได้ อ่านง่ายและพิมพ์ง่ายขึ้น

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
โปรดตรวจสอบฉันจะเขียนคำตอบที่ดีได้อย่างไร คำตอบที่ไม่ใช้รหัสเท่านั้นไม่ได้รับการสนับสนุนเนื่องจากไม่ได้อธิบายว่าจะแก้ไขปัญหาในคำถามได้อย่างไร คุณควรอัปเดตคำตอบของคุณเพื่ออธิบายว่าสิ่งนี้ทำอะไรได้บ้างและปรับปรุงให้ดีขึ้นอย่างไรกับคำตอบ upvoted ที่คำถามนี้มีอยู่แล้ว
FluffyKitten

1

ถ้าฉันจะกำหนด proptypes ที่เหมือนกันสำหรับรูปร่างเฉพาะหลาย ๆ ครั้งฉันชอบ abstract มันออกเป็นไฟล์ proptypes เพื่อที่ว่าถ้ารูปร่างของวัตถุเปลี่ยนไปฉันจะต้องเปลี่ยนรหัสในที่เดียว มันช่วยทำให้ codebase แห้งไปเล็กน้อย

ตัวอย่าง:

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

1

นี่เป็นวิธีแก้ปัญหาของฉันเพื่อป้องกันอาร์เรย์ว่างเปล่าเช่นกัน:

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`)
    }
  }
}
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.