ReactJs: PropTypes nên làm gì cho this.props.children?


265

Cho một thành phần đơn giản làm cho con của nó:

class ContainerComponent extends Component {
  static propTypes = {
    children: PropTypes.object.isRequired,
  }

  render() {
    return (
      <div>
        {this.props.children}
      </div>
    );
  }
}

export default ContainerComponent;

Câu hỏi: propType của trẻ em nên là gì?

Khi tôi đặt nó làm đối tượng, nó sẽ thất bại khi tôi sử dụng thành phần có nhiều con:

<ContainerComponent>
  <div>1</div>
  <div>2</div>
</ContainerComponent>

Cảnh báo: Không loại prop: prop không hợp lệ childrencủa loại hình array cung cấp cho ContainerComponent, dự kiến object.

Nếu tôi đặt nó dưới dạng một mảng, nó sẽ thất bại nếu tôi chỉ cho nó một con, tức là:

<ContainerComponent>
  <div>1</div>
</ContainerComponent>

Cảnh báo: Loại prop không thành công: Các prop prop không hợp lệ của đối tượng loại được cung cấp cho ContainerComponent, mảng dự kiến.

Xin tư vấn, tôi có nên không bận tâm đến việc kiểm tra propTypes cho các yếu tố trẻ em không?


Bạn có thể muốnnode
lux


2
Vui lòng xem câu trả lời của tôi dưới đây mô tả nhiều tùy chọn hơn, nhưng, nếu bạn đang tìm kiếm thành phần con thì đó là PropTypes.element. PropTypes.node mô tả bất cứ điều gì có thể được kết xuất - chuỗi, số, phần tử hoặc một mảng của những điều này. Nếu điều này phù hợp với bạn thì đây là cách.
ggilberth

Câu trả lời:


369

Hãy thử một cái gì đó như thế này bằng cách sử dụng oneOfType hoặcPropTypes.node

import PropTypes from 'prop-types'

...

static propTypes = {
    children: PropTypes.oneOfType([
        PropTypes.arrayOf(PropTypes.node),
        PropTypes.node
    ]).isRequired
}

hoặc là

static propTypes = {
    children: PropTypes.node.isRequired,
}

1
Đáng tiếc là nó không thành công với các lỗi tương tự trong trường hợp đứa trẻ duy nhất: "Cảnh báo: Không thể chống đỡ loại: prop không hợp lệ childrencủa loại hình object. ... dự kiến một mảng"
d3ming

25
Điều đó đã làm việc! Giải pháp đơn giản nhất là children: PropTypes.node, làm việc cho cả hai trường hợp. Cảm ơn những lời đề nghị =)
d3ming

6
Điều duy nhất làm cho câu trả lời này rõ ràng hơn là nếu bạn bao gồm một ghi chú tương tự như câu trả lời của @ggilberth để giải thích React.PropTypes.nodemô tả bất kỳ đối tượng có thể kết xuất nào.
theotherjim

Không cần mảng, chỉ cần PropTypes.node. Điều đó xử lý các sửa lỗi sau: không có gì, chuỗi, phần tử đơn, một số phần tử, đoạn, thành phần.
Dima Tisnek

38

Đối với tôi nó phụ thuộc vào thành phần. Nếu bạn biết những gì bạn cần nó sẽ được phổ biến thì bạn nên cố gắng chỉ định riêng hoặc nhiều loại bằng cách sử dụng:

PropTypes.oneOfType 

Tuy nhiên, tôi chủ yếu tìm thấy, với các thành phần chung hơn có thể có nhiều loại trẻ em, tôi rất vui khi sử dụng:

PropTypes.any

Nếu bạn muốn tham khảo một thành phần React thì bạn sẽ tìm kiếm

PropTypes.element

Mặc du,

PropTypes.node

mô tả bất cứ điều gì có thể được kết xuất - chuỗi, số, phần tử hoặc một mảng của những điều này. Nếu điều này phù hợp với bạn thì đây là cách.


7
Proptypes.anylà loại quá phổ biến. Eslint không hài lòng với điều đó.
Alex Shwarc

20

Tài liệu PropTypes có những điều sau đây

// Anything that can be rendered: numbers, strings, elements or an array
// (or fragment) containing these types.
optionalNode: PropTypes.node,

Vì vậy, bạn có thể sử dụng PropTypes.nodeđể kiểm tra các đối tượng hoặc mảng của các đối tượng

static propTypes = {
   children: PropTypes.node.isRequired,
}

12

Các câu trả lời ở đây dường như không bao gồm việc kiểm tra chính xác trẻ em. nodeobjectquá dễ dãi, tôi muốn kiểm tra yếu tố chính xác. Đây là những gì tôi đã kết thúc bằng cách sử dụng:

  • Sử dụng oneOfType([]) để cho phép một hoặc một mảng của trẻ em
  • Sử dụng shapearrayOf(shape({})) cho một và các mảng tương ứng của trẻ em
  • Sử dụng oneOfcho chính phần tử con

Cuối cùng, một cái gì đó như thế này:

import PropTypes from 'prop-types'
import MyComponent from './MyComponent'

children: PropTypes.oneOfType([
  PropTypes.shape({
    type: PropTypes.oneOf([MyComponent]),
  }),
  PropTypes.arrayOf(
    PropTypes.shape({
      type: PropTypes.oneOf([MyComponent]),
    })
  ),
]).isRequired

Vấn đề này đã giúp tôi tìm hiểu rõ hơn: https://github.com/facebook/react/issues/2979


5

Nếu bạn muốn khớp chính xác một loại thành phần, hãy kiểm tra cái này

MenuPrimary.propTypes = {
  children: PropTypes.oneOfType([
    PropTypes.arrayOf(MenuPrimaryItem),
    PropTypes.objectOf(MenuPrimaryItem)
  ])
}

Nếu bạn muốn khớp chính xác một số loại thành phần, hãy kiểm tra điều này

const HeaderTypes = [
  PropTypes.objectOf(MenuPrimary),
  PropTypes.objectOf(UserInfo)
]

Header.propTypes = {
  children: PropTypes.oneOfType([
    PropTypes.arrayOf(PropTypes.oneOfType([...HeaderTypes])),
    ...HeaderTypes
  ])
}

2

Hãy thử một propTypes tùy chỉnh:

 const  childrenPropTypeLogic = (props, propName, componentName) => {
          const prop = props[propName];
          return React.Children
                   .toArray(prop)
                   .find(child => child.type !== 'div') && new Error(`${componentName} only accepts "div" elements`);
 };


static propTypes = {

   children : childrenPropTypeLogic

}

Vĩ cầm


0

Thí dụ:

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

class MenuItem extends React.Component {
    render() {
        return (
            <li>
                <a href={this.props.href}>{this.props.children}</a>
            </li>
        );
    }
}

MenuItem.defaultProps = {
    href: "/",
    children: "Main page"
};

MenuItem.propTypes = {
    href: PropTypes.string.isRequired,
    children: PropTypes.string.isRequired
};

export default MenuItem;

Ảnh: Hiển thị lỗi của bạn trong bảng điều khiển nếu loại dự kiến ​​khác

Ảnh: Hiển thị lỗi của bạn trong bảng điều khiển nếu loại dự kiến ​​khác

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.