<div> ไม่สามารถปรากฏเป็นลูกหลานของ <p>


140

ฉันเห็นสิ่งนี้ ไม่ใช่เรื่องลึกลับที่บ่นเกี่ยวกับ:

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

ฉันเป็นผู้เขียนSomeComponentและSomeOtherComponent. แต่หลังใช้การพึ่งพาภายนอก ( ReactTooltipจากreact-tooltip) อาจไม่จำเป็นว่านี่คือการพึ่งพาภายนอก แต่ให้ฉันลองใช้อาร์กิวเมนต์ที่นี่ว่าเป็น "รหัสบางอย่างที่ไม่สามารถควบคุมได้"

ฉันควรกังวลแค่ไหนเกี่ยวกับคำเตือนนี้เนื่องจากส่วนประกอบที่ซ้อนกันทำงานได้ดี (ดูเหมือน) และฉันจะเปลี่ยนสิ่งนี้อย่างไรต่อไป (หากฉันไม่ต้องการใช้การอ้างอิงภายนอกอีกครั้ง) อาจจะมีการออกแบบที่ดีกว่าที่ฉันยังไม่รู้อีกหรือไม่?

SomeOtherComponentเพื่อประโยชน์ครบถ้วนนี่คือการดำเนินงานของ เพียงแค่แสดงผลthis.props.valueและเมื่อวางเมาส์: คำแนะนำเครื่องมือที่ระบุว่า "ข้อความคำแนะนำเครื่องมือบางอย่าง":

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>
  }
}

ขอขอบคุณ.


1
ปัญหาที่เกี่ยวข้อง: github.com/wwayne/react-tooltip/issues/210
Jordan Running

คำตอบ:


138

หากข้อผิดพลาดนี้เกิดขึ้นขณะใช้ Material UI <Typography> https://material-ui.com/api/typography/คุณสามารถเปลี่ยน<p>เป็น a ได้อย่างง่ายดาย<span>โดยเปลี่ยนค่าของcomponentแอตทริบิวต์ของ<Typography>องค์ประกอบ:

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

ตามเอกสารการพิมพ์:

ส่วนประกอบ: ส่วนประกอบที่ใช้สำหรับโหนดรูท ไม่ว่าจะเป็นสตริงเพื่อใช้องค์ประกอบ DOM หรือส่วนประกอบ โดยค่าเริ่มต้นจะแมปตัวแปรกับองค์ประกอบบรรทัดแรกเริ่มต้นที่ดี

ดังนั้น Typography จึงถูกเลือก<p>เป็นค่าเริ่มต้นที่สมเหตุสมผลซึ่งคุณสามารถเปลี่ยนแปลงได้ อาจมาพร้อมกับผลข้างเคียง ... ได้ผลสำหรับฉัน


เป็นเรื่องโชคร้ายในแง่ของ SEO โดยเฉพาะอย่างยิ่งหากคุณต้องการให้องค์ประกอบเป็นส่วนหัว (เพื่อให้เป็นที่รู้จัก) แต่มีตัวแปรเช่น h4
pfeds

ในการพิจารณาเพิ่มเติมดูเหมือนว่าคุณสามารถมีองค์ประกอบการพิมพ์รากที่มีตัวแปร = "สืบทอด" (เช่นที่ระดับหน้า) จากนั้นจึงมีส่วนประกอบของ Typography ย่อย = "h1" variant = "h5" ดูเหมือนว่าจะได้ผล แต่ฉันไม่แน่ใจว่าฉันใช้ Typography อย่างถูกวิธี ...
pfeds

8
ฉันใช้<Typography component={'div'}>และใช้งานได้โดยไม่มีคำเตือนในขณะนี้ ขอบคุณมากที่ทำให้ฉันมาถูกทาง!
JohnK

ฉันต้องการตัวพิมพ์เพื่อห่อหุ้ม div ของฉันเพื่อให้ข้อความของฉันแสดงอย่างถูกต้องบนหน้า หากไม่มีมันเป็นองค์ประกอบหลักคลาส css ของฉันดูเหมือนจะไม่ได้ลงทะเบียนอย่างถูกต้องแปลกใช่มั้ย? อย่างไรก็ตามสิ่งนี้ใช้งานได้เหมือนมีเสน่ห์ css ลงทะเบียนและมันลบข้อผิดพลาดของฉันหวาน!
C.Gadd

79

ตามข้อความเตือนส่วนประกอบ ReactTooltip จะแสดงผล HTML ที่อาจมีลักษณะดังนี้:

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

ตามนี้เอกสารที่มี<p></p>แท็กเท่านั้นที่สามารถมีองค์ประกอบแบบอินไลน์ นั่นหมายถึงการใส่<div></div>แท็กไว้ข้างในนั้นควรจะไม่เหมาะสมเนื่องจากdivแท็กเป็นองค์ประกอบบล็อก การซ้อนที่ไม่เหมาะสมอาจทำให้เกิดข้อผิดพลาดเช่นการแสดงแท็กเพิ่มเติมซึ่งอาจส่งผลต่อจาวาสคริปต์และ css ของคุณ

หากคุณต้องการลบคำเตือนนี้คุณอาจต้องการปรับแต่งคอมโพเนนต์ ReactTooltip หรือรอให้ผู้สร้างแก้ไขคำเตือนนี้


ดังนั้นใช่ฉันเข้าใจสิ่งที่ได้รับการแสดงผล แต่คุณก็จะบอกว่าส่วนประกอบใด ๆ ที่ทำให้divควรจะ refactored ในโอกาสที่จะถูกนำมาใช้ในส่วนp? ดูเหมือนว่าจะบินไปเผชิญหน้ากับความนิยมอย่างมากdivสำหรับการห่อของโดยพลการ?
Sander Verhagen

2
ฉันเดาอย่างนั้นเนื่องจากอยู่ในคำแนะนำของ w3c นอกจากนี้เราได้อย่างง่ายดายสามารถแทนที่divด้วยspanเพื่อหลีกเลี่ยงชนิดของคำเตือนนี้ แต่ไม่มีผลกระทบต่ออะไรในตรรกะของรหัส
JD Hernandez

1
หากคุณได้รับข้อผิดพลาดนี้เมื่อใช้ Material UI <Typography> โดยตรงคุณสามารถเปลี่ยน "องค์ประกอบ" ซึ่งฉันอธิบายไว้ด้านล่างในคำตอบของฉัน หวังว่านี่จะช่วยได้
zayquan

ลองใช้ <span> แทน <div> ภายใน <p> ของคุณ - ควรแก้ไขได้ ฉันพบข้อผิดพลาดนี้โดยใช้ <div> สำหรับการแสดงรูปภาพที่เป็นแหล่งที่มาถูกระบุโดยคลาส css หลัก
Christopher Stock


17

ส่วนประกอบของคุณอาจแสดงผลภายในองค์ประกอบอื่น (เช่น a <Typography> ... </Typography>) ดังนั้นมันจะโหลดส่วนประกอบของคุณภายใน<p> .. </p>ที่ไม่ได้รับอนุญาต

แก้ไข: ลบออก<Typography>...</Typography>เนื่องจากใช้สำหรับข้อความธรรมดาภายใน<p>...</p>องค์ประกอบข้อความหรือองค์ประกอบข้อความอื่น ๆ เช่นส่วนหัวเท่านั้น


4
ฉันใช้<Typography component={'div'}>และใช้งานได้โดยไม่มีคำเตือนในขณะนี้ ขอบคุณมากที่ทำให้ฉันมาถูกทาง!
JohnK

11

ฉันได้รับคำเตือนนี้โดยใช้ส่วนประกอบUI ของวัสดุจากนั้นฉันทดสอบcomponent="div"as prop กับโค้ดด้านล่างและทุกอย่างถูกต้อง:

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

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

อันที่จริงคำเตือนนี้เกิดขึ้นเนื่องจากใน UI วัสดุแท็ก HTML เริ่มต้นของGridองค์ประกอบคือdivแท็กและTypographyแท็ก HTML เริ่มต้นคือpแท็กดังนั้นคำเตือนจึงเกิดขึ้น

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

พูดสั้น ๆ ว่า UI ของวัสดุมีข้อบกพร่องหรือไม่?
Ero Stefano

1
ไม่มี @EroStefano ที่รักนี่เป็นเจตนาที่นักพัฒนาทำตามกฎลำดับชั้นของระดับอินไลน์และระดับบล็อก
AmerllicA

8

นี่เป็นข้อ จำกัด ของเบราว์เซอร์ คุณควรใช้ div หรือ article หรืออะไรทำนองนั้นในวิธีการเรนเดอร์ของแอพเพราะวิธีนี้คุณสามารถใส่อะไรก็ได้ที่คุณต้องการ แท็กย่อหน้าถูก จำกัด ให้มีชุดแท็กที่ จำกัด เท่านั้น (ส่วนใหญ่เป็นแท็กสำหรับการจัดรูปแบบข้อความคุณไม่สามารถมี div ภายในย่อหน้าได้

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

ไม่ใช่ HTML ที่ถูกต้อง แท็กต่อกฎละเลยที่ระบุไว้ในสเปคที่<p>แท็กจะปิดโดยอัตโนมัติโดย<div>แท็กซึ่งใบแท็กโดยไม่ต้องจับคู่</p> <p>เบราว์เซอร์มีสิทธิ์ในการพยายามแก้ไขโดยการเพิ่ม<p>แท็กที่เปิดอยู่หลังจาก<div>:

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

คุณไม่สามารถใส่<div>ภายใน<p>และได้รับผลสอดคล้องกันจากเบราว์เซอร์ต่างๆ จัดเตรียม HTML ที่ถูกต้องให้เบราว์เซอร์และจะทำงานได้ดีขึ้น

คุณสามารถใส่<div>ภายใน<div>แม้ว่าดังนั้นหากคุณแทนที่คุณ<p>มี<div class="p">และรูปแบบได้อย่างเหมาะสมคุณจะได้รับสิ่งที่คุณต้องการ


1
แล้วคุณจะติดตามสิ่งนี้ได้อย่างไร? ข้อผิดพลาดกำลังเข้าแถว
ichimaru

7

คำเตือนจะปรากฏขึ้นเนื่องจากรหัสสาธิตมี:

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>
  );
}

การเปลี่ยนเช่นนี้จะดูแลมัน:

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>
    );
}

4

ฉันมีปัญหาที่คล้ายกันและรวมองค์ประกอบไว้ใน "div" แทนที่จะเป็น "p" และข้อผิดพลาดก็หายไป


2

หากคุณกำลังใช้ReactTooltipเพื่อทำให้คำเตือนหายไปตอนนี้คุณสามารถเพิ่มwrapperเสาด้วยค่าspanดังนี้:

<ReactTooltip wrapper="span" />

เนื่องจากspanเป็นองค์ประกอบแบบอินไลน์จึงไม่ควรบ่นอีกต่อไป


2

ฉันได้รับสิ่งนี้จากการใช้ส่วนประกอบที่กำหนดเองภายใน<Card.Text>ส่วนของ<Card>ส่วนประกอบใน React ไม่มีส่วนประกอบของฉันอยู่ในแท็ก p


0

ฉันได้รับข้อผิดพลาดนี้เมื่อใช้ Chakra UI ใน React เมื่อทำการจัดแต่งทรงผมแบบอินไลน์สำหรับข้อความบางส่วน วิธีที่ถูกต้องในการจัดแต่งทรงผมแบบอินไลน์คือการใช้องค์ประกอบช่วงตามที่คนอื่น ๆ กล่าวไว้สำหรับกรอบรูปแบบอื่น รหัสที่ถูกต้อง:

<Text as="span" fontWeight="bold">
    Bold text
    <Text display="inline" fontWeight="normal">normal inline text</Text>
</Text>
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.