javascript - 语义 UI 中的表主体没有表行导致 validateDomNesting 错误

标签 javascript reactjs redux semantic-ui-react

我已经浏览了所有与此有关的示例问题,但似乎无法弄清楚我的问题是什么。

这是完整的错误:

index.js:1375 Warning: validateDOMNesting(...): Text nodes cannot appear as a child of <tbody>.
    in tbody (created by TableBody)
    in TableBody (at Favorites.js:167)
    in table (created by Table)
    in Table (at Favorites.js:123)
    in Favorites (created by ConnectFunction)
    in ConnectFunction (at App.js:73)
    in Route (at App.js:69)
    in Router (created by BrowserRouter)
    in BrowserRouter (at App.js:46)
    in div (created by Container)
    in Container (at App.js:44)
    in App (created by ConnectFunction)
    in ConnectFunction (at src/index.js:10)
    in Provider (at src/index.js:9)

和我的完整代码

import React, { useState, useEffect } from "react";
import Search from "./Search";
import { connect } from "react-redux";
import {
  Table,
  Popup,
  Responsive,
  Button,
  Segment,
  Header,
  Image
} from "semantic-ui-react";
import { searchChange } from "../reducers/searchReducer";
import { fetchData } from "../reducers/baseballReducer";
import { removeFavorite } from "../reducers/favoriteReducer";
import { getFavorites } from "../reducers/favoriteReducer";
import { getUpdates } from "../reducers/updateReducer";
import { setNotification } from "../reducers/notificationReducer";
import _ from "lodash";
var moment = require("moment");
moment().format();

//Filter 'favupdates' state for user's input
const searchCards = ({ favUpdates, search }) => {
  return search
    ? favUpdates.filter(a =>
        a.title
          .toString()
          .toLowerCase()
          .includes(search.toLowerCase())
      )
    : favUpdates;
};

const style = {
  borderRadius: 0,
  padding: "2em"
};

const Favorites = props => {
  useEffect(() => {
    document.title = "My Favorites | All Vintage Search";
  }, []);

  useEffect(() => {
    props.getFavorites(props.loggedUser.id);
  }, [props.loggedUser]);

  //Set 'filteredData' state
  useEffect(() => {
    setData(props.cardsToShow);
  }, [props]);

  const mapFAVS = props.favorites;
  const data = Array.from(mapFAVS);
  const updatedFavs = data.map(item => item.id);
  const formatFavs = updatedFavs.map(id => id.join(","));
  console.log("FORMAT FAVS", formatFavs);

  //Get updated data from eBay based on user's favorite id's and update 'favUpdates' state
  useEffect(() => {
    props.getUpdates(formatFavs);
  }, [props.favorites]);

  const [column, setColumn] = useState(null);
  const [direction, setDirection] = useState(null);
  const [filteredData, setData] = useState(props.cardsToShow);

  console.log("Filtered Data", filteredData);

  const handleSortNumeric = clickedColumn => {
    const sorter = data => parseInt(data[clickedColumn]);
    setData(_.sortBy(filteredData, sorter));
  };

  const handleSortReverse = () => {
    const sorter = data => parseInt(data);
    setData(_.sortBy(filteredData, sorter).reverse());
  };

  const handleSort = clickedColumn => {
    if (column !== clickedColumn) {
      setColumn(clickedColumn);
      if (clickedColumn === "title" || "acceptsOffers" || "timeStamp") {
        setData(_.sortBy(filteredData, [clickedColumn]));
      } else {
        handleSortNumeric(clickedColumn);
      }
      setDirection("ascending");
      return;
    }

    if (clickedColumn === "title") {
      setData(_.sortBy(filteredData.reverse()));
    } else {
      handleSortReverse();
    }

    direction === "ascending"
      ? setDirection("descending")
      : setDirection("ascending");
  };

  const removeFavorite = card => {
    props.removeFavorite(card, props.loggedUser);
    props.setNotification(`You removed ${card.title}!`, 5);
  };

  if (!props.cardsToShow) return null;

  return (
    <>
      <Search />
      <Segment inverted color="blue">
        <Header inverted color="grey" size="medium">
          My Favorites
        </Header>
      </Segment>
      <Segment>Count: {props.cardsToShow.length}</Segment>
      <Responsive maxWidth={767}>
        <strong>Click to Sort:</strong>
      </Responsive>
      <Table sortable celled fixed striped>
        <Table.Header>
          <Table.Row>
            <Table.HeaderCell
              textAlign="center"
              sorted={column === "title" ? direction : null}
              onClick={() => handleSort("title")}
            >
              Card Title
            </Table.HeaderCell>
            <Table.HeaderCell
              width={2}
              textAlign="center"
              sorted={column === "updatedBids" ? direction : null}
              onClick={() => handleSort("updatedBids")}
            >
              # Bids
            </Table.HeaderCell>
            <Table.HeaderCell
              textAlign="center"
              sorted={column === "updatedPrice" ? direction : null}
              onClick={() => handleSort("updatedPrice")}
            >
              Price
            </Table.HeaderCell>
            <Table.HeaderCell
              textAlign="center"
              sorted={column === "timeStamp" ? direction : null}
              onClick={() => handleSort("timeStamp")}
            >
              Time Left
            </Table.HeaderCell>
            <Table.HeaderCell
              textAlign="center"
              sorted={column === "status" ? direction : null}
              onClick={() => handleSort("status")}
            >
              Status
            </Table.HeaderCell>
            <Table.HeaderCell textAlign="center" width={2}>
              Remove
            </Table.HeaderCell>
          </Table.Row>
        </Table.Header>
        <Table.Body>
          {!filteredData
            ? "Sorry No Cards Found"
            : filteredData.map(card => (
                <>
                  <Responsive maxWidth={767}>
                        <div className="ui piled compact segment">
                          <div className="ui card">
                            <div className="blurring dimmable image">
                              <div className="ui inverted dimmer">
                                <div className="content">
                                  <div className="center">
                                    <div className="ui red button view">
                                      VIEW
                                    </div>
                                  </div>
                                </div>
                              </div>
                              <Image
                                src={card.image}
                                href={card.itemURL}
                                centered
                                style={{ padding: "5px" }}
                              />
                            </div>
                            <div className="content">
                              <div
                                id="rate"
                                className="ui star rating right floated"
                                data-rating="3"
                              ></div>
                              <div className="header">
                                <a href={card.itemURL}>{card.title}</a>
                              </div>
                              <div
                                className="meta"
                                style={{ padding: "5px 0 0 0" }}
                              >
                                <span className="date">
                                  <i className="clock icon"></i> Ends in{" "}
                                  {moment
                                    .duration(card.timeLeft, "minutes")
                                    .humanize()}
                                </span>
                                <div style={{ padding: "10px 0 0 0" }}>
                                  <span>
                                    <Button color="green">
                                      ${card.updatedPrice}
                                    </Button>
                                  </span>
                                  <span class="right floated date">
                                    {" "}
                                    <Button
                                      onClick={() => removeFavorite(card)}
                                      color="red"
                                      icon="remove circle"
                                    />
                                  </span>
                                </div>
                              </div>
                            </div>
                            <div className="extra content">
                              <div
                                className="ui right labeled button"
                                data-content="Bids"
                                data-variation="tiny"
                                tabindex="0"
                              >
                                <div className="ui blue icon tiny button">
                                  <i className="gavel large icon"></i>
                                </div>
                                <a
                                  href={card.itemURL}
                                  className="ui basic blue left pointing label"
                                >
                                  {card.updatedBids}
                                </a>
                              </div>
                              <div
                                className="ui left labeled right floated button"
                                data-content="Watch Count"
                                data-variation="tiny"
                                tabindex="0"
                              >
                                <a
                                  href={card.itemURL}
                                  className="ui basic blue right pointing label"
                                >
                                  {card.status}
                                </a>
                                <div className="ui blue icon tiny button">
                                  <i className="history large icon"></i>
                                </div>
                              </div>
                            </div>
                          </div>
                        </div>
                  </Responsive>
                  <Responsive
                    as={"tr"}
                    minWidth={768}
                    style={{ width: "100%" }}
                  >
                    <Popup
                      trigger={
                        <Table.Cell>
                          <a href={card.itemURL} target={"_blank"}>
                            {card.title}
                          </a>
                        </Table.Cell>
                      }
                      content={
                        <img
                          alt={card.title}
                          src={card.image}
                          height="250"
                        ></img>
                      }
                      style={style}
                      size="small"
                      position="left center"
                    ></Popup>
                    <Table.Cell textAlign="center">
                      {card.updatedBids}
                    </Table.Cell>
                    <Table.Cell textAlign="center">
                      ${card.updatedPrice}
                    </Table.Cell>
                    <Table.Cell textAlign="center">
                      {moment.duration(card.timeLeft, "minutes").humanize()}
                    </Table.Cell>
                    <Table.Cell textAlign="center">{card.status}</Table.Cell>
                    <Table.Cell textAlign="center">
                      <Button
                        onClick={() => removeFavorite(card)}
                        color="red"
                        icon="remove circle"
                      />
                    </Table.Cell>
                  </Responsive>
                </>
              ))}
        </Table.Body>
        <Table.Footer>
          <Table.Row>
            <Table.HeaderCell colSpan="6"></Table.HeaderCell>
          </Table.Row>
        </Table.Footer>
      </Table>
    </>
  );
};

const mapStateToProps = state => {
  return {
    baseball: state.baseball,
    favorites: state.favorites,
    favUpdates: state.favUpdates,
    loggedUser: state.loggedUser,
    page: state.page,
    entries: state.entries,
    query: state.query,
    pageOutput: state.pageOutput,
    search: state.search,
    cardsToShow: searchCards(state)
  };
};

const mapDispatchToProps = {
  searchChange,
  fetchData,
  removeFavorite,
  getFavorites,
  getUpdates,
  setNotification
};

export default connect(mapStateToProps, mapDispatchToProps)(Favorites);

我怀疑问题可能出在我使用该部分的位置,因为我在表体中没有设置任何表行或单元格。我尝试用 Table.Row 和 Table.Cell 包装整个部分,但仍然遇到相同的错误。有什么想法吗?

最佳答案

如果!filteredData === false那么<Table.Body>的独生子是文本。

正如错误所示,表格主体不能将文本作为子项。

将文本换行如下 <Table.Row><Table.Cell>Sorry no cards shown</Table.Cell></Table.Row>

关于javascript - 语义 UI 中的表主体没有表行导致 validateDomNesting 错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59587065/

相关文章:

javascript - 如何在 WOPI 中使用 Discovery XML?

javascript - 为什么必须使用关键字 "this"而不是类名?

javascript - 无法导入 react js组件

node.js - 即使在建立 Websocket 之后,Socket IO 仍保持(重新?)连接

javascript - 这段 ES6 代码做了什么?

javascript - 使用 Materialise 和 Meteor 时应该在哪里初始化 select?

javascript - Sequelize 6.13.4 版的 requestTimeout 的替代方案是什么?

javascript - 如何在 false 时触发函数?

typescript - React Router 的参数不起作用

javascript - fetch api 从服务器获取错误消息而不是通用消息