<div> không được xuất hiện dưới dạng con của <p>


112

Tôi đang thấy điều này. Nó không phải là một bí ẩn những gì nó đang phàn nàn:

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

Tôi là tác giả của SomeComponentSomeOtherComponent. Nhưng sau này là sử dụng một phụ thuộc bên ngoài ( ReactTooltiptừ react-tooltip). Có lẽ không cần thiết rằng đây là một phụ thuộc bên ngoài, nhưng nó cho phép tôi thử lập luận ở đây rằng đó là "một số mã ngoài tầm kiểm soát của tôi".

Tôi nên lo lắng đến mức nào về cảnh báo này, vì thành phần lồng nhau đang hoạt động tốt (dường như)? Và tôi sẽ làm cách nào để thay đổi điều này (miễn là tôi không muốn triển khai lại một phần phụ thuộc bên ngoài)? Có thể có một thiết kế tốt hơn mà tôi chưa biết không?

Vì lợi ích hoàn chỉnh, đây là cách thực hiện SomeOtherComponent. Nó chỉ hiển thị this.props.valuevà khi được di chuột qua: một chú giải công cụ cho biết "Một số thông báo chú giải công cụ":

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

Cảm ơn bạn.


Câu trả lời:


109

Nếu lỗi này xảy ra khi sử dụng Material UI <Typography> https://material-ui.com/api/typography/ , thì bạn có thể dễ dàng thay đổi <p>thành a <span>bằng cách thay đổi giá trị của componentthuộc tính của <Typography>phần tử:

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

Theo các tài liệu về kiểu chữ:

component: Thành phần được sử dụng cho nút gốc. Là một chuỗi để sử dụng một phần tử DOM hoặc một thành phần. Theo mặc định, nó ánh xạ biến thể đến một thành phần dòng tiêu đề mặc định tốt.

Vì vậy, Typography được chọn <p>làm mặc định hợp lý, bạn có thể thay đổi. Có thể đi kèm với các tác dụng phụ ... đã làm việc cho tôi.


Thật không may về mặt SEO, đặc biệt nếu bạn muốn thành phần là tiêu đề (được công nhận), nhưng với một biến thể của một cái gì đó như h4.
pfeds

Về vấn đề xa hơn, có vẻ như bạn có thể có một phần tử Typography gốc với biến thể = "inherit" (tức là ở cấp độ trang), và sau đó là một thành phần Typography phụ = "h1" variant = "h5". Nó có vẻ hoạt động, nhưng tôi không hoàn toàn chắc chắn rằng tôi đang sử dụng Typography đúng cách ...
pfeds

5
Tôi đã sử dụng <Typography component={'div'}>và nó hoạt động mà không có cảnh báo ngay bây giờ. Cảm ơn bạn rất nhiều vì đã đưa tôi đi đúng hướng!
JohnK

Tôi cần một kiểu chữ để đóng gói div của mình để văn bản của tôi hiển thị chính xác trên trang. Nếu không có nó như một phần tử cha, lớp css của tôi dường như không được đăng ký chính xác, kỳ lạ phải không? Tuy nhiên điều này hoạt động như một cái duyên, css đã đăng ký và nó loại bỏ lỗi của tôi, ngọt ngào!
C.Gadd

2
Đây là câu trả lời tiết kiệm thời gian thực
YaakovHatam

74

Dựa trên thông báo cảnh báo, thành phần ReactTooltip hiển thị một HTML có thể trông giống như sau:

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

Theo tài liệu này , <p></p>thẻ chỉ có thể chứa các phần tử nội tuyến. Điều đó có nghĩa là việc đặt một <div></div>thẻ bên trong nó phải không đúng cách, vì divthẻ là một phần tử khối. Việc lồng ghép không đúng cách có thể gây ra trục trặc như hiển thị các thẻ phụ , có thể ảnh hưởng đến javascript và css của bạn.

Nếu bạn muốn loại bỏ cảnh báo này, bạn có thể muốn tùy chỉnh thành phần ReactTooltip hoặc đợi người tạo khắc phục cảnh báo này.


Vì vậy, vâng, tôi hiểu những gì được kết xuất, nhưng sau đó bạn có nói rằng bất kỳ thành phần nào hiển thị a divnên được cấu trúc lại, nếu có cơ hội được sử dụng trong a p? Có vẻ như nó đang bay khi đối mặt với cách rất phổ biến divcho việc gói đồ tùy tiện?
Sander Verhagen

2
Tôi đoán vậy, vì nó nằm trong khuyến nghị w3c. Ngoài ra, chúng tôi có thể dễ dàng thay thế a divbằng a spanđể tránh loại cảnh báo này nhưng không ảnh hưởng đến bất kỳ điều gì trong logic của mã.
JD Hernandez

1
Nếu bạn gặp lỗi này khi sử dụng trực tiếp Material UI <Typography>, bạn có thể thay đổi "thành phần" mà tôi mô tả bên dưới trong câu trả lời của mình. Hy vọng điều này sẽ hữu ích
zayquan 10/1218

Hãy thử sử dụng <span> thay vì <div> bên trong <p> của bạn - Điều này sẽ khắc phục được. Tôi đã gặp phải lỗi này khi sử dụng <div> để hiển thị hình ảnh mà nguồn được chỉ định bởi một lớp css mẹ.
Christopher Stock

18

Nếu bạn đang tìm kiếm nơi điều này đang xảy ra, trong bảng điều khiển, bạn có thể sử dụng: document.querySelectorAll(" p * div ")


16

Thành phần của bạn có thể được hiển thị bên trong một thành phần khác (chẳng hạn như a <Typography> ... </Typography>). Do đó, nó sẽ tải thành phần của bạn bên trong một thành phần <p> .. </p>không được phép.

Khắc phục: Loại bỏ <Typography>...</Typography>vì điều này chỉ được sử dụng cho văn bản thuần túy bên trong một <p>...</p>hoặc bất kỳ phần tử văn bản nào khác, chẳng hạn như tiêu đề.


4
Tôi đã sử dụng <Typography component={'div'}>và nó hoạt động mà không có cảnh báo ngay bây giờ. Cảm ơn bạn rất nhiều vì đã đưa tôi đi đúng hướng!
JohnK

8

Tôi nhận được cảnh báo này bằng cách sử dụng các thành phần Material UI , sau đó tôi kiểm tra phần component="div"hỗ trợ cho đoạn mã dưới đây và mọi thứ đều trở nên chính xác:

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

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

Trên thực tế, cảnh báo này xảy ra vì trong giao diện người dùng Material, thẻ HTML mặc định của Gridthành phần là divthẻ và Typographythẻ HTML mặc định là pthẻ, Vì vậy, bây giờ cảnh báo sẽ xảy ra,

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

Nói ngắn gọn Material UI có lỗi?
Ero Stefano

1
Không có @EroStefano thân mến, đây là chủ ý mà nhà phát triển tuân theo quy tắc phân cấp của cấp nội tuyến và cấp khối.
AmerllicA

4

Tôi đã gặp sự cố tương tự và gói thành phần trong "div" thay vì "p" và lỗi đã biến mất.


4

Đây là một hạn chế của các trình duyệt. Bạn nên sử dụng div hoặc article hoặc thứ gì đó tương tự trong phương thức kết xuất của Ứng dụng vì bằng cách đó, bạn có thể đặt bất cứ thứ gì bạn thích vào bên trong nó. Các thẻ đoạn văn bị giới hạn chỉ chứa một bộ thẻ giới hạn (chủ yếu là các thẻ để định dạng văn bản. Bạn không thể có một div bên trong một đoạn văn

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

không phải là HTML hợp lệ. Theo quy tắc bỏ qua thẻ được liệt kê trong thông số kỹ thuật, <p>thẻ sẽ tự động được đóng bởi <div>thẻ, điều này khiến </p>thẻ không có khớp <p>. Trình duyệt có quyền cố gắng sửa nó bằng cách thêm một <p>thẻ mở sau <div>:

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

Bạn không thể đặt <div>bên trong a <p>và nhận được kết quả nhất quán từ các trình duyệt khác nhau. Cung cấp cho các trình duyệt HTML hợp lệ và chúng sẽ hoạt động tốt hơn.

Bạn có thể đặt <div>bên trong một <div>mặc dù vậy nếu bạn thay thế của bạn <p>với <div class="p">và phong cách nó một cách thích hợp, bạn có thể có được những gì bạn muốn.


1
vậy làm thế nào để bạn theo dõi điều này? các lỗi đang xếp hàng
ichimaru

2

Nếu bạn đang sử dụng ReactTooltip, để làm cho cảnh báo biến mất, bây giờ bạn có thể thêm wrappermột giá trị có giá trị span, như sau:

<ReactTooltip wrapper="span" />

spanlà một phần tử nội tuyến, nó sẽ không còn phàn nàn nữa.


Bạn là người bạn tốt nhất của tôi, tốt nhất trong những điều tốt nhất. Yêu bạn.
AmerllicA

2

Tôi có được điều này từ việc sử dụng một thành phần tùy chỉnh bên trong một <Card.Text>phần của một <Card>thành phần trong React. Không có thành phần nào của tôi nằm trong thẻ p


2

Cảnh báo chỉ xuất hiện vì mã demo có:

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

Thay đổi nó như thế này sẽ chăm sóc nó:

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>
    );
}
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.