ReactJs: Bagaimana seharusnya PropTypes untuk this.props.children?


265

Diberikan komponen sederhana yang menjadikan anak-anaknya:

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

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

export default ContainerComponent;

Pertanyaan: Seperti apa seharusnya proptype anak-anak?

Ketika saya menetapkannya sebagai objek, itu gagal ketika saya menggunakan komponen dengan beberapa anak:

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

Peringatan: Gagal jenis prop: prop valid childrenjenis array dipasok ke ContainerComponent, diharapkan object.

Jika saya mengaturnya sebagai array, itu akan gagal jika saya berikan hanya satu anak, yaitu:

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

Peringatan: Jenis penyangga gagal: Anak-anak penyangga tidak valid dari objek jenis yang dipasok ke ContainerComponent, array yang diharapkan.

Mohon saran, haruskah saya tidak repot-repot melakukan pemeriksaan propTypes untuk elemen anak-anak?


Anda mungkin inginnode
— lux


2
Silakan lihat jawaban saya di bawah ini yang menjelaskan lebih banyak opsi, tetapi, jika Anda mencari komponen anak maka PropTypes.element. PropTypes.node menjelaskan segala sesuatu yang dapat ditampilkan - string, angka, elemen atau array dari hal-hal ini. Jika ini cocok untuk Anda maka inilah caranya.
— ggilberth

Jawaban:


369

Coba sesuatu seperti ini menggunakan oneOfTypeatauPropTypes.node

import PropTypes from 'prop-types'

...

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

atau

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

1
Sayangnya gagal dengan kesalahan yang sama dalam kasus anak tunggal: "Peringatan: Gagal jenis prop: prop valid childrenjenis object. ... diharapkan array"
— d3ming

25
Itu berhasil! Solusi paling sederhana adalah children: PropTypes.node, yang bekerja untuk kedua kasus. Terima kasih atas sarannya =)
— d3ming

6
Satu-satunya hal yang akan membuat jawaban ini menjadi lebih jelas adalah jika Anda menyertakan catatan yang mirip dengan jawaban @ggilberth untuk menjelaskan yang React.PropTypes.nodemenjelaskan objek apa pun yang dapat di render.
— theotherjim

Tidak perlu array, cukup PropTypes.node. Itu menangani koreksi berikut: tidak ada, string, elemen tunggal, beberapa elemen, fragmen, komponen.
— Dima Tisnek

38

Bagi saya itu tergantung pada komponennya. Jika Anda tahu apa yang Anda butuhkan untuk diisi maka Anda harus mencoba menentukan secara eksklusif, atau beberapa jenis menggunakan:

PropTypes.oneOfType 

Namun saya kebanyakan menemukan, dengan komponen yang lebih umum yang dapat memiliki banyak jenis anak, saya senang menggunakan:

PropTypes.any

Jika Anda ingin merujuk ke komponen Bereaksi maka Anda akan mencari

PropTypes.element

Meskipun,

PropTypes.node

menjelaskan apa saja yang dapat diterjemahkan - string, angka, elemen atau array dari hal-hal ini. Jika ini cocok untuk Anda maka inilah caranya.


7
Proptypes.anytipe yang terlalu umum. Eslint tidak senang dengan itu.
— Alex Shwarc

20

Dokumentasi PropTypes memiliki yang berikut ini

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

Jadi, Anda dapat menggunakan PropTypes.nodeuntuk memeriksa objek atau array objek

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

12

Jawaban di sini tampaknya tidak cukup mencakup memeriksa anak-anak persis. nodedan objectterlalu permisif, saya ingin memeriksa elemen yang tepat. Inilah yang akhirnya saya gunakan:

  • Gunakan oneOfType([])untuk memungkinkan satu atau berbagai anak
  • Gunakan shapedan arrayOf(shape({}))untuk lajang dan anak-anak, masing-masing
  • Gunakan oneOfuntuk elemen anak itu sendiri

Pada akhirnya, sesuatu seperti ini:

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

Masalah ini membantu saya memahami hal ini dengan lebih jelas: https://github.com/facebook/react/issues/2979


5

Jika Anda ingin mencocokkan jenis komponen dengan tepat, periksa ini

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

Jika Anda ingin mencocokkan dengan tepat beberapa jenis komponen, periksa ini

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

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

2

Coba propTipe khusus:

 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

}

Biola


0

Contoh:

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;

Gambar: Menunjukkan kesalahan Anda di konsol jika jenis yang diharapkan berbeda

Gambar: Menunjukkan kesalahan Anda di konsol jika jenis yang diharapkan berbeda

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.