<div> tidak dapat muncul sebagai keturunan dari <p>

123

Saya melihat ini. Bukan misteri apa yang dikeluhkan:

Warning: validateDOMnesting(...): <div> cannot appear as a descendant of <p>. See ... SomeComponent > p > ... > SomeOtherComponent > ReactTooltip > div.

Saya penulis SomeComponentdan SomeOtherComponent. Tetapi yang terakhir menggunakan ketergantungan eksternal ( ReactTooltipdari react-tooltip). Mungkin tidak penting bahwa ini adalah ketergantungan eksternal, tetapi ini memungkinkan saya mencoba argumen di sini bahwa ini adalah "beberapa kode yang di luar kendali saya".

Seberapa khawatirnya saya tentang peringatan ini, mengingat komponen bersarang berfungsi dengan baik (tampaknya)? Dan bagaimana saya akan mengubah ini (asalkan saya tidak ingin menerapkan kembali ketergantungan eksternal)? Apakah mungkin ada desain yang lebih baik yang belum saya sadari?

Demi kelengkapan, berikut implementasinya SomeOtherComponent. Ini hanya merender this.props.value, dan saat diarahkan: keterangan alat yang mengatakan "Beberapa pesan keterangan alat":

class SomeOtherComponent extends React.Component {
  constructor(props) {
    super(props)
  }

  render() {
    const {value, ...rest} = this.props;
    return <span className="some-other-component">
      <a href="#" data-tip="Some tooltip message" {...rest}>{value}</a>
      <ReactTooltip />
    </span>
  }
}

Terima kasih.

Sander Verhagen
sumber
1
Masalah terkait: github.com/wwayne/react-tooltip/issues/210
Jordan Menjalankan

Jawaban:

120

Jika kesalahan ini terjadi saat menggunakan UI Material <Typography> https://material-ui.com/api/typography/ , maka Anda dapat dengan mudah mengubah <p>ke a <span>dengan mengubah nilai componentatribut <Typography>elemen:

<Typography component={'span'} variant={'body2'}>

Menurut dokumen tipografi:

komponen: Komponen yang digunakan untuk simpul akar. Baik string untuk menggunakan elemen DOM atau komponen. Secara default, ini memetakan varian ke komponen judul default yang baik.

Jadi Tipografi dipilih <p>sebagai default yang masuk akal, yang dapat Anda ubah. Mungkin datang dengan efek samping ... bekerja untuk saya.

zayquan
sumber
Sangat disayangkan dalam hal SEO, terutama jika Anda ingin komponennya menjadi tajuk (dikenali), tetapi dengan varian seperti h4.
pfeds
Pada faffing lebih lanjut, tampaknya Anda dapat memiliki elemen Tipografi root dengan variant = "inherit" (yaitu di tingkat halaman), dan kemudian sub Tipografi component = "h1" variant = "h5". Tampaknya berhasil, tetapi saya tidak sepenuhnya yakin saya menggunakan Tipografi dengan cara yang benar ...
pfeds
6
Saya menggunakan <Typography component={'div'}>dan berfungsi tanpa peringatan sekarang. Terima kasih banyak telah menempatkan saya di jalur yang benar!
JohnK
Saya membutuhkan tipografi untuk merangkum div saya sehingga teks saya ditampilkan dengan benar di halaman. Tanpa itu sebagai elemen induk, kelas css saya sepertinya tidak terdaftar dengan benar, aneh bukan? Namun ini bekerja seperti pesona, css terdaftar dan menghapus kesalahan saya, manis!
C. Gadd
3
Ini adalah jawaban penghemat waktu nyata
YaakovHatam
76

Berdasarkan pesan peringatan, komponen ReactTooltip merender HTML yang mungkin terlihat seperti ini:

<p>
   <div>...</div>
</p>

Menurut dokumen ini , <p></p>tag hanya boleh berisi elemen sebaris. Itu berarti meletakkan <div></div>tag di dalamnya seharusnya tidak tepat, karena divtag tersebut adalah elemen blok. Penyarangan yang tidak tepat dapat menyebabkan gangguan seperti merender tag tambahan , yang dapat memengaruhi javascript dan css Anda.

Jika Anda ingin menghilangkan peringatan ini, Anda mungkin ingin menyesuaikan komponen ReactTooltip, atau menunggu pembuatnya memperbaiki peringatan ini.

JD Hernandez
sumber
Jadi, ya, saya mengerti apa yang dirender, tetapi apakah Anda kemudian akan mengatakan bahwa setiap komponen yang merender a divharus difaktorisasi ulang, dengan kemungkinan digunakan dalam a p? Tampaknya terbang di hadapan betapa sangat populernya divuntuk membungkus barang secara sewenang-wenang?
Sander Verhagen
2
Saya rasa begitu, karena ada dalam rekomendasi w3c. Selain itu, kami dapat dengan mudah mengganti a divdengan a spanuntuk menghindari peringatan semacam ini tetapi tanpa memengaruhi apa pun dalam logika kode.
JD Hernandez
1
Jika Anda mendapatkan kesalahan ini saat menggunakan Material UI <Typography> secara langsung Anda dapat mengubah "komponen", yang saya jelaskan di bawah ini dalam jawaban saya. Semoga ini bisa membantu
zayquan
Coba gunakan <span> alih-alih <div> di dalam <p> Anda - Ini harus memperbaikinya. Saya mengalami kesalahan ini dengan menggunakan <div> untuk menampilkan gambar yang sumbernya ditentukan oleh kelas css induk.
Christopher Stock
21

Jika Anda mencari di mana ini terjadi, di konsol Anda dapat menggunakan: document.querySelectorAll(" p * div ")

Alex C
sumber
17

Komponen Anda mungkin dirender di dalam komponen lain (seperti a <Typography> ... </Typography>). Oleh karena itu, ini akan memuat komponen Anda di dalam <p> .. </p>yang tidak diperbolehkan.

Perbaiki: Hapus <Typography>...</Typography>karena ini hanya digunakan untuk teks biasa di dalam <p>...</p>atau elemen teks lainnya seperti judul.

Dion Duimel
sumber
4
Saya menggunakan <Typography component={'div'}>dan berfungsi tanpa peringatan sekarang. Terima kasih banyak telah menempatkan saya di jalur yang benar!
JohnK
11

Saya mendapat peringatan ini dengan menggunakan komponen Material UI , kemudian saya menguji component="div"sebagai prop ke kode di bawah ini dan semuanya menjadi benar:

import Grid from '@material-ui/core/Grid';
import Typography from '@material-ui/core/Typography';

<Typography component="span">
  <Grid component="span">
    Lorem Ipsum
  </Grid>
</Typography>

Sebenarnya peringatan ini terjadi karena di Material UI tag HTML default Gridkomponen adalah divtag dan Typographytag HTML default adalah ptag, Jadi sekarang peringatan itu terjadi,

Warning: validateDOMnesting(...): <div> cannot appear as a descendant of <p>
AmerllicA
sumber
Singkatnya, Material UI memiliki bug?
Ero Stefano
1
Tidak sayang @EroStefano, ini disengaja agar pengembang mengikuti aturan hierarki level sebaris dan blok.
AmerllicA
6

Ini adalah kendala browser. Anda harus menggunakan div atau artikel atau sesuatu seperti itu dalam metode render App karena dengan cara itu Anda dapat memasukkan apapun yang Anda suka di dalamnya. Tag paragraf dibatasi hanya berisi kumpulan tag terbatas (kebanyakan tag untuk memformat teks. Anda tidak boleh memiliki div di dalam paragraf

<p><div></div></p>

bukan HTML yang valid. Sesuai aturan penghilangan tag yang tercantum dalam spesifikasi, <p>tag secara otomatis ditutup oleh <div>tag, yang meninggalkan </p>tag tanpa pencocokan <p>. Browser berhak mencoba untuk memperbaikinya dengan menambahkan <p>tag terbuka setelah <div>:

<p></p><div></div><p></p>

Anda tidak dapat memasukkannya ke <div>dalam <p>dan mendapatkan hasil yang konsisten dari berbagai browser. Menyediakan browser dengan HTML yang valid dan mereka akan berperilaku lebih baik.

Anda dapat memasukkannya ke <div>dalam <div>sehingga jika Anda mengganti <p>dengan <div class="p">dan menatanya dengan tepat, Anda bisa mendapatkan apa yang Anda inginkan.

jithu
sumber
1
jadi bagaimana Anda melacak ini? kesalahan berbaris
ichimaru
5

Peringatan muncul hanya karena kode demo memiliki:

function TabPanel(props) {
  const { children, value, index, ...other } = props;

  return (
    <div
      role="tabpanel"
      hidden={value !== index}
      id={`simple-tabpanel-${index}`}
      aria-labelledby={`simple-tab-${index}`}
      {...other}
    >
      {value === index && (
        <Box p={3}>  // <==NOTE P TAG HERE
          <Typography>{children}</Typography>
        </Box>
      )}
    </div>
  );
}

Mengubahnya seperti ini menanganinya:

function TabPanel(props) {
    const {children, value, index, classes, ...other} = props;

    return (
        <div
            role="tabpanel"
            hidden={value !== index}
            id={`simple-tabpanel-${index}`}
            aria-labelledby={`simple-tab-${index}`}
            {...other}
        >
            {value === index && (
                <Container>
                    <Box>   // <== P TAG REMOVED
                        {children}
                    </Box>
                </Container>
            )}
        </div>
    );
}
VikR
sumber
1
Tuhan memberkati Anda. Membuang begitu banyak waktu untuk meneliti komponen saya sendiri
M. Dada
4

Saya mengalami masalah serupa dan membungkus komponen dalam "div" bukan "p" dan kesalahan itu hilang.

jbluft.dll
sumber
2

Jika Anda menggunakan ReactTooltip, untuk menghilangkan peringatan, Anda sekarang dapat menambahkan wrapperprop dengan nilai span, seperti ini:

<ReactTooltip wrapper="span" />

Karena spanadalah elemen inline, seharusnya tidak ada lagi komplain.

Nicco
sumber
Kamu adalah yang terbaik temanku, yang terbaik dari yang terbaik. Cinta kamu.
AmerllicA
2

Saya mendapatkan ini dari menggunakan komponen khusus di dalam <Card.Text>bagian <Card>komponen di React. Tak satu pun dari komponen saya berada dalam tag p

BitShift
sumber