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.