React: Peringatan untuk: PropTypes.object.isRequired saat prop `null`

Dibuat pada 16 Feb 2015  ·  37Komentar  ·  Sumber: facebook/react

Karena PropTypes adalah tentang 'tipe' prop, null adalah objek kosong, tetapi secara praktis masih merupakan tipe objek.

Tapi tetap saja itu memperingatkan:

 Warning: Required prop `profile` was not specified in `Element`. Check the render method of `OtherElement`.

Saya tidak berpikir ini seharusnya terjadi.

Itu berhenti memperingatkan setelah bukan null lagi. Saya cukup yakin itu hanya akan memperingatkan ketika undefined ?

Komentar yang paling membantu

Kasus penggunaan umum yang saya lihat adalah React merender komponen sebelum panggilan API untuk data selesai. Render pertama akan merender, misalnya, daftar item ( items: null ). Kemudian panggilan API selesai, dan sekarang items diisi dengan array.

Semua 37 komentar

null setara dengan tanpa nilai dan bukan objek (kosong atau sebaliknya). Jika Anda tidak ingin memperingatkan null maka jangan membuatnya diperlukan, itu memiliki efek yang sama. Menguji keberadaan kunci bukanlah sesuatu yang saya sarankan.

Saya setuju. Saya tidak dapat memikirkan banyak kasus penggunaan di mana Anda ingin memaksa pengguna untuk menentukan nilai, tetapi bersedia menerima null sebagai nilai yang valid. Untuk tujuan praktis, peringatan isRequired untuk null adalah perilaku yang masuk akal dan diharapkan.

terkait: https://github.com/facebook/react/issues/2166
(masalah ini masih muncul dengan jelas di hasil pencarian)

Kasus penggunaan umum yang saya lihat adalah React merender komponen sebelum panggilan API untuk data selesai. Render pertama akan merender, misalnya, daftar item ( items: null ). Kemudian panggilan API selesai, dan sekarang items diisi dengan array.

Saya mencoba melakukan PropTypes.oneOfType([null, PropTypes.object]).isRequired , jadi null atau objek, apakah ini tidak mungkin sekarang?

Menurut CHANGELOG , karena 15.4.0 itu seharusnya mungkin

Sebenarnya, kebalikan dari 15.4.0: Required PropTypes now fail with specific messages for null and undefined.

Saya juga menghadapi masalah ini.
Solusi @Noitidart tidak berfungsi untuk saya. Itu melempar kesalahan yang mengatakan:
Failed prop type: The prop nilai is marked as required in Pilih , but its value is null .

Saya merasa sangat berguna untuk meminta properti tetapi juga mengizinkan nilai nol.

+1 untuk mengizinkan null entah bagaimana.

Kami memiliki kasus penggunaan di mana konfigurasi kami dimuat melalui JSON, dan ada beberapa opsi konfigurasi label yang menentukan string yang harus ditampilkan, seperti ini:

{
  "title": "my title"
}

Jadi ketika tidak ada judul yang ditampilkan, kami menggunakan null untuk menunjukkan kasus itu:

{
  "title": null
}

(Menambahkan hasTitle: false paralel akan menjadi penghalang karena kami memiliki lusinan pengaturan ini.)

Untuk konten JSON, menggunakan null adalah cara yang sangat berguna untuk membedakan antara yang tidak didefinisikan ( undefined ) versus yang sengaja dihilangkan ( null ).

anda dapat mengizinkan null, atur propType agar tidak diperlukan, karena itu tidak diperlukan :P

@jquense terima kasih itu sangat membantu! Saya telah menghapus komentar saya sebelumnya karena jawaban SO ini mengatakan hal yang sama.

@jquense Anda dapat mengizinkan null DAN tidak terdefinisi, tetapi tidak satu atau yang lain.

Itulah masalahnya! Javascript menyediakan 2 konstruksi berbeda ini karena suatu alasan, jadi memaksa semua orang untuk memperlakukan null === undefined untuk PropTypes adalah batasan buatan.

Hanya karena saya ingin PropType secara eksplisit mengizinkan null tidak berarti saya harus mengizinkan yang tidak terdefinisi juga. Mereka adalah dua kasus yang berbeda, dan bahasa sengaja merancangnya seperti itu.

Saya memiliki PR untuk mengatasi pengawasan ini di sini: https://github.com/facebook/prop-types/pull/90

Saya ingin melarang undefined karena itu berarti ada kesalahan ketik dan mengizinkan null karena itu berarti penelepon secara eksplisit memasukkan null . Itulah inti dari masalah ini. Saya mengerti bahwa masalah ini ditutup karena disarankan untuk beralih ke aliran, yang akan saya periksa.

@binki Salah satu cara untuk mengizinkan null tetapi tidak undefined adalah dengan menggunakan fungsi validator PropType Anda sendiri.

Dalam contoh di bawah, hanya null atau string yang diizinkan. Pustaka PropTypes menggunakan typeof internal untuk memeriksa string, jadi saya melakukan hal yang sama. Salah satu manfaatnya adalah Anda dapat memindahkan fungsi ini di luar komponen Anda dan memanggilnya sesuai kebutuhan.

static propTypes = {
  id: PropTypes.number.isRequired,
  email: function(props, propName, componentName) {
    const propValue = props[propName] // the actual value of `email` prop
    if (propValue === null) return
    if (typeof propValue === 'string') return
    return new Error(`${componentName} only accepts null or string`)
  }
}

Saya kira solusi ini menyimpang dari maksud perpustakaan PropTypes - alasan saya mengatakan ini karena kode di bawah ini dari perpustakaan PropTypes di https://github.com/facebook/prop-types/blob/master/factoryWithTypeCheckers.js #L189.

Sebelum benar-benar memvalidasi, pemeriksaan cepat dilakukan di mana properti yang disetel dengan isRequired secara otomatis membuat kesalahan jika nilai properti adalah null . Dengan kata lain mereka percaya bahwa properti yang diperlukan menjadi nol itu salah sedangkan saya menganggapnya sebagai kasus penggunaan yang valid untuk memiliki nol yang diperlukan.

if (props[propName] == null) {
  if (isRequired) {
    if (props[propName] === null) {
      return new PropTypeError('The ' + location + ' `' + propFullName + '` is marked as required ' + ('in `' + componentName + '`, but its value is `null`.'));
    }
    return new PropTypeError('The ' + location + ' `' + propFullName + '` is marked as required in ' + ('`' + componentName + '`, but its value is `undefined`.'));
  }
  return null;
} else {
  return validate(props, propName, componentName, location, propFullName);
}

Saya setuju dengan @ jharris4 untuk alasan yang disebutkan. null tidak sama dengan undefined . Ini adalah standar untuk menggunakannya sebagai pengganti.

Dari Jaringan Pengembang Mozilla:

Nilai null mewakili ketidakhadiran yang disengaja dari nilai objek apa pun.

null bukan pengidentifikasi untuk properti objek global, seperti yang tidak dapat ditentukan. Sebaliknya, null menyatakan kurangnya identifikasi, yang menunjukkan bahwa variabel tidak menunjuk ke objek. Di API, null sering diambil di tempat di mana objek dapat diharapkan tetapi tidak ada objek yang relevan.

null harus diizinkan, setidaknya melalui PropTypes.oneOfType([null, PropTypes.string]).isRequired .

@jquense — Menghapus isRequired berarti Anda mungkin harus menetapkan default. Apakah ini berarti Anda sekarang akan menetapkan default untuk nilai awal dalam komponen _and_ di peredam, semua untuk menghindari memungkinkan null sebagai nilai untuk prop?

Saya memiliki banyak data || '' ( isRequired menerima string kosong '' , objek kosong {} , dll.) di penyebab pemilih saya sambil menunggu panggilan API ke finish null adalah hal yang sempurna untuk memberitahu komponen bahwa data akan datang tunggu sebentar! (tapi aku tidak bisa melakukan itu...)
@ puiu91 memiliki pekerjaan yang baik di sekitar untuk saat ini ... aku harus membuat fungsi utilitas untuk menggunakan seluruh basis kode kita ... karena sepertinya masalah ini tidak mendapatkan dibuka kembali dalam waktu dekat mendesah

Saya juga setuju harus ada cara standar untuk menerima null sebagai nilai, untuk alasan yang sama @jharris4 dan @Findiglay menyatakan, tetapi ini bukan tempat untuk melanjutkan diskusi lagi. Masalah ini tidak hanya ditutup, tetapi juga milik facebook/prop-types . Saya mengikuti permintaan tarik di sini facebook/prop-types#90.

Menabrak. Masih mengalami ini hari ini. Akan sangat bagus untuk memiliki dukungan bawaan untuk sesuatu seperti:

myObj: PropType.object.isRequiredOrNull :)

Saya pikir prioritas ini sangat rendah. Flow adalah cara yang direkomendasikan untuk pergi. http://flow.org/

@Marujah cuplikan Anda tidak benar.

Coba berikan null ke komponen, dan Anda akan melihat bahwa Anda akan mendapatkan peringatan:

Warning: Failed prop type: The prop 'theProp' is marked as required in 'TheComponent', but its value is null.

Masalahnya adalah isRequired dievaluasi terlebih dahulu dan tidak akan pernah membiarkan nilai nol atau tidak terdefinisi masuk.

PR ke prop-types untuk memperbaiki masalah ditautkan di atas jika Anda tertarik.

Oh memang! tes ulang lagi kamu benar

Mengharuskan bahwa suatu nilai atau nol harus diberikan secara khusus harus benar-benar diizinkan melalui PropTypes.

Inilah kasus penggunaan yang saya hadapi. Kami memiliki beberapa panggilan balik yang diperlukan oleh 90% pemilih kami. Beberapa yang tidak membutuhkannya adalah kasus penggunaan yang sangat spesifik. Kami memiliki beberapa pengembang baru yang terus-menerus lupa untuk memberikan semua panggilan balik yang biasa.

Saya ingin memaksa semua penggunaan Komponen ini untuk membuat keputusan sadar untuk tidak menyertakan panggilan balik tertentu, daripada seseorang yang hanya melupakan beberapa alat peraga.

Ya, kami dapat meretas pemeriksaan kami sendiri yang lebih spesifik melalui aliran, tetapi itu membagi validasi alat peraga kami menjadi dua tempat, dan agak tidak intuitif bagi seseorang yang melirik definisi propTypes.

Hanya ingin menambahkan kasus penggunaan saya di sini. Saya memiliki toko redux dengan data beserta kapan data itu diambil, jika ada kesalahan, dll. Komponen saya memerlukan penyangga 'kesalahan' (sehingga dapat menampilkan kesalahan kepada pengguna jika data tidak dapat diambil), yang nol ketika data berhasil dimuat, tetapi diisi ketika ada kesalahan.

Saya melewatkan komponen pemuat ( PropTypes.node ) sebagai props , dan ketika saya tidak ingin membuat pemuat, saya meneruskan null .
Afaik, fungsi render harus mengembalikan null alih-alih undefined saat tidak merender apa pun. Jadi melewatkan null sebagai nilainya terlihat seperti cara yang benar untuk melakukannya pada saya.

Saya menerapkan komponen InputNumber (pembungkus untuk <input type="number"> ), jadi saya memiliki propTypes untuk prop saya valuePropTypes.number.isRequired , dan ketika saya menggunakan komponen saya, saya selalu melewatinya properti. Tetapi hari ini saya harus memberikan tautan nullable secara default ke nilai, dan komponen saya menambahkan peringatan. Satu-satunya keputusan yang dapat saya bayangkan adalah mengubah propTypes untuk prop saya value menjadi PropTypes.oneOfType([PropTypes.number, PropTypes.string]) dan menetapkan defaultProps sebagai null. Tapi saya merasa itu bukan yang benar karena input type=number seharusnya bekerja dengan angka saja.

Saya mencoba melakukan PropTypes.oneOfType([null, PropTypes.object]).isRequired , jadi null atau objek, apakah ini tidak mungkin sekarang?

Ia mengharapkan sebuah fungsi: Warning: Invalid argument supplied to oneOfType. Expected an array of check functions, but received null at index 1.

Jadi, Anda harus menyediakan fungsi, seperti:

PropTypes.oneOfType([
  () => null,
  PropTypes.object
]).isRequired

Baru saja menemukan bug ini, saya telah menulis fungsi kenyamanan untuk mengatasinya:

function nullable(subRequirement) {
  const check = (required, props, key, ...rest) => {
    if (props[key] === null) {
      return null;
    }
    const sub = required ? subRequirement.isRequired : subRequirement;
    return sub(props, key, ...rest);
  };
  const fn = check.bind(null, false);
  fn.isRequired = check.bind(null, true);
  return fn;
}

Penggunaan:

static propTypes = {
  someCallbackFunction: nullable(PropTypes.func).isRequired,
};

Mungkin (tetapi tidak ada gunanya) menggunakan nullable tanpa isRequired . Alasan saya membuatnya kompatibel dengan isRequired adalah agar dapat bekerja dengan aturan eslint react/require-default-props .

Kasus penggunaan saya adalah serangkaian komponen yang sesuai dengan API umum, dibungkus oleh satu komponen yang menangani panggilan balik. null callback berarti 'hanya baca', jadi komponen pembungkus terkadang dengan sengaja melewatkan null s. Pada saat yang sama, setiap properti harus diteruskan ke subkomponen untuk memastikan bahwa jika properti baru ditambahkan, properti tersebut tidak akan terlewatkan. Saya juga tidak ingin memberikan defaultProps null untuk setiap komponen yang sesuai dengan API ini; sejauh yang mereka ketahui, penelepon harus menentukan nilai.

Saya mengambil helper yang saya tulis sebelumnya dan memasukkannya ke dalam paket bersama dengan banyak tes untuk membuktikan kebenarannya:

npm install --save git+https://github.com/davidje13/prop-types-nullable.git#semver:^1.0.0

Penggunaan:

import PropTypes from 'prop-types';
import nullable from 'prop-types-nullable';

[...]

static propTypes = {
  thing: nullable(PropTypes.string).isRequired,
};

Solusi baru: PropTypes.oneOfType([PropTypes.object]).isRequired

Saya mendapatkan kesalahan.
bagaimana cara memperbaiki.

PERINGATAN dalam ./~/prop-types/prop-types.js Dependensi kritis: 1:482-489 Ini tampaknya merupakan file javascript yang dibuat sebelumnya. Meskipun ini mungkin, itu tidak disarankan. Cobalah untuk meminta sumber asli untuk mendapatkan hasil yang lebih baik. @ ./~/prop-types/prop-types.js 1:482-489

Saya mencoba melakukan PropTypes.oneOfType([null, PropTypes.object]).isRequired , jadi null atau objek, apakah ini tidak mungkin sekarang?

Ia mengharapkan sebuah fungsi: Warning: Invalid argument supplied to oneOfType. Expected an array of check functions, but received null at index 1.

Jadi, Anda harus menyediakan fungsi, seperti:

PropTypes.oneOfType([
  () => null,
  PropTypes.object
]).isRequired

Sebenarnya saya mengalami kesalahan karena 'isRequired' pada akhirnya, menjadi nol dan diperlukan pada saat yang sama tidak kompatibel ...
Inilah yang berhasil untuk saya:

PropTypes.oneOfType([ 
    PropTypes.string.isRequired, 
    () => null 
])

@gugol2 harap dicatat bahwa apa yang Anda tulis hanya akan menonaktifkan pemeriksaan tipe sepenuhnya (Anda sekarang dapat memberikan nomor ke prop itu, atau undefined , atau apa pun); fungsi yang Anda berikan harus mengembalikan null jika validasi berhasil dan non- null jika gagal.

Jika Anda ingin menempuh rute itu, Anda memerlukan sesuatu yang lebih seperti:

PropTypes.oneOfType([
  PropTypes.string.isRequired,
  (props, key) => props[key] === null ? null : 'Not null'
])

Tentu saja Anda dapat menentukan terlebih dahulu fungsi pembantu yang tampak buruk:

const nullable = (props, key) => props[key] === null ? null : 'Not null'

// ...

PropTypes.oneOfType([PropTypes.string.isRequired, nullable])

Ini juga sangat mungkin (tapi saya benar-benar tidak akan merekomendasikannya!) untuk hanya menggunakan PropTypes.oneOfType([PropTypes.string.isRequired]) . Ini terasa seperti bug dan saya tidak berharap kode seperti itu bertahan di versi yang lebih baru. Perhatikan juga bahwa ini mirip dengan, tetapi tidak sama dengan, metode yang


Jika Anda bisa menunggu, ada PR terbuka yang bergerak sangat lambat tetapi tampaknya masih dalam pertimbangan.

Dan sampai PR digabungkan, saya akan merekomendasikan menggunakan paket yang saya buat (atau kode di belakangnya ) karena dengan cara itu Anda bisa meletakkan .isRequired di akhir baris, yang membuatnya kompatibel dengan aturan linting.

IMHO ini adalah perilaku yang benar tetapi harus didokumentasikan.

Kasus penggunaan umum yang saya lihat adalah React merender komponen sebelum panggilan API untuk data selesai. Render pertama akan merender, misalnya, daftar item ( items: null ). Kemudian panggilan API selesai, dan sekarang items diisi dengan array.

Adakah cara terbaik untuk menangani ini? Saya ingin prop ini diperlukan TAPI itu nol sebelum saya mendapatkannya kembali dari API.

PropTypes.oneOfType([
  PropTypes.string.isRequired,
  (props, key) => props[key] === null ? null : 'Not null'
])

@ davidje13 saya mengalami sedikit masalah dengan pendekatan ini. Pengujian cakupan memiliki 1/4 kasus yang tidak pernah tercakup.

Katakanlah saya memiliki Login komponen yang hanya memiliki satu 'nama' prop yang dapat berupa null atau string yang diperlukan:

const Login = ({name}) => {
  return <div>{name}</div>
} 

Jadi proptype-nya adalah:

Login.propTypes = {
  name: PropTypes.oneOfType([
    PropTypes.string.isRequired,
    (props, key) => (props[key] === null ? null : 'Not null'),
  ]),
};

Ketika saya menguji komponen ini, saya benar-benar hanya memiliki 2 skenario, null ATAU string yang diperlukan.

render(<Login name={null} />
render(<Login name={'anyName'} />

Tetapi cakupan memberi tahu saya bahwa pengujian saya hanya memiliki cakupan 75%.
Saya ingin tahu apa yang akan menjadi pendekatan resmi untuk ini.

Sepertinya test case Anda yang hilang adalah yang gagal dalam pemeriksaan prop? yaitu jika Anda memberikan nomor atau tidak terdefinisi atau sesuatu yang lain seharusnya tidak.

Sepertinya test case Anda yang hilang adalah yang gagal dalam pemeriksaan prop? yaitu jika Anda memberikan nomor atau tidak terdefinisi atau sesuatu yang lain seharusnya tidak.

Tidak, bukan itu.

Melewati undefined tidak memperluas cakupan.
Dan saya tidak bisa memberikan angka, itu bukan nilai yang diizinkan.

Saya tidak bisa menutupi kasus itu.

Apakah halaman ini membantu?
0 / 5 - 0 peringkat