【问题标题】:Make the rows of Semantic UI's Table clickable使 Semantic UI Table 的行可点击
【发布时间】:2020-08-24 08:53:21
【问题描述】:

该表是来自Semantic UI 的表。

使行可点击的一种方法是添加Link from react-router-dom

喜欢这里:

import React from 'react';
import { Table } from 'semantic-ui-react';
import { Link } from 'react-router-dom'; // used for Link

export default class GenericTable extends React.PureComponent {
  constructor(props) {
    super(props);
  }

  render() {
    const {
      headers,
      emptyFirstHeader,
      rows,
      id,
      entityName,
      idList,
    } = this.props;

    return (
      <Table id={id}>
        <Table.Header>
          <Table.Row>
            <Table.HeaderCell />
          </Table.Row>
        </Table.Header>

        <Table.Body>
          {rows.map((row, rowIndex) => (
            <Table.Row
              key={idList && idList[rowIndex]}
              as={Link} // this line makes the row clickable but also adds the errors
              to={entityName && `/${entityName}/${idList[rows.indexOf(row)]}`}> // the location of the redirect
              {row.cells.map((cell, cellIndex) => {
                if (cell === undefined) {
                  return null;
                }
                return (
                  <Table.Cell
                    key={idList && `${idList[rowIndex]} ${headers[cellIndex]}`}>
                    {cell}
                  </Table.Cell>
                );
              })}
            </Table.Row>
          ))}
        </Table.Body>
      </Table>
    );
  }
}

问题是它在开发者工具中返回错误:

index.js:1 Warning: validateDOMNesting(...): <td> cannot appear as a child of <a>.
in td (created by TableCell)
in TableCell (at GenericTable.js:193)
in a (created by LinkAnchor)
in LinkAnchor (created by Context.Consumer)
in Link (created by TableRow)
in TableRow (at GenericTable.js:143)
in tbody (created by TableBody)
in TableBody (at GenericTable.js:141)
in table (created by Table)
in Table (at GenericTable.js:105)

尝试通过将as={Link} 替换为onClick 并将其连接到单独的函数来解决此问题。该错误消息现在消失了,但是当单击一行时,它不会重定向到所需的页面。

我在函数内部添加了一个 console.log 来检查它是否被调用。

这是代码:

  navigateTo = (entityName, idList, rows, row) => {
    console.log('click: ', entityName, row); // the log works
    return (
      <Link to={entityName && `/${entityName}/${idList[rows.indexOf(row)]}`} />
    );
  };

...
            <Table.Body>
              {rows.map((row, rowIndex) => (
                <Table.Row
                  key={idList && idList[rowIndex]}
                  onClick={() => {
                    this.navigateTo(entityName, idList, rows, row);
                  }}
                  to={entityName && `/${entityName}/${idList[rows.indexOf(row)]}`}> // the location of the redirect
                  {row.cells.map((cell, cellIndex) => {
                    if (cell === undefined) {
                      return null;
                    }
                    return (
                      <Table.Cell
                        key={idList && `${idList[rowIndex]} ${headers[cellIndex]}`}>
                        {cell}
                      </Table.Cell>
                    );
                  })}
                </Table.Row>
              ))}
            </Table.Body>

任何想法为什么不起作用以及应该如何修改?

【问题讨论】:

  • 当用户点击行时你想做什么。重定向到另一条路线?
  • @ShubhamVerma 是的。从链接到路线
  • 如果可能的话,您可以将此代码添加到代码和框。基本上你需要反应路由器的帮助才能在行点击时推送路由
  • @ShubhamVerma 不幸的是,它无法添加到沙箱中,我可以说的是,当它具有 as={Link} 时,它会在单击一行但出现该错误时重定向到该页面(这也会影响CSS样式,不知道为什么),当它有onClick={() ... }时,它不再有那个错误但是当它被点击时它不会重定向。

标签: javascript reactjs react-router semantic-ui react-router-dom


【解决方案1】:

在您使用&lt;Table.Row as={Link} /&gt; 时,控制台会打印出这些错误(更准确地说是警告),因为这样做会将tr 元素呈现为a,所以这就是DOM 的样子在这种方法中:

&lt;td&gt; cannot appear as a child of &lt;a&gt;

&lt;a&gt; cannot appear as a child of &lt;tbody&gt;

这只是一个警告,不应干扰其余的脚本执行,因此重定向仍然按照您的指示工作。但是,它会记录警告,正如您所描述的,这也会导致样式问题 - 因为现在 tr 已转换为 a 标记。

为了挽救这个 Link 实现,您可以将这些链接作为 td 元素的子元素。

<Table.Body>
  {rows.map((row, rowIndex) => (
    <Table.Row
      key={idList && idList[rowIndex]}
    >
      {row.cells.map((cell, cellIndex) => {
        if (cell === undefined) {
          return null;
        }
        return (
          <Table.Cell
            key={idList && `${idList[rowIndex]} ${headers[cellIndex]}`}>
            <Link to={entityName && `/${entityName}/${idList[rows.indexOf(row)]}`}>{cell}</Link>
          </Table.Cell>
        );
      })}
    </Table.Row>
  ))}
</Table.Body>

这将消除控制台警告,因为现在,a 标签现在是 td 的子标签,这是有效的 HTML 结构。请注意,您可能需要对整行进行一些 CSS 重构才能使其可点击。您需要扩展每个a 标签以适应tr 的高度和其父td 的宽度。


对此更理想的解决方案是像您尝试的那样利用Table.RowonClick 属性。但是,在您的尝试中,这并没有真正重定向用户,因为它只是在单击时返回一些 JSX - 实际上并没有发生任何路由。

要挽救这个onClick 实现,您可以使用withRouter 高阶组件。

import { withRouter } from "react-router-dom";

class GenericTable extends React.PureComponent { ... }

export default withRouter(props => <GenericTable {...props} />);

我们可以使用与您相同的 onClick 属性,但我们将重构 navigateTo 方法上的一些代码

navigateTo = (entityName, idList, rows, row) => {
  console.log('click: ', entityName, row); // the log works
  entityName && this.props.history.push(`/${entityName}/${idList[rows.indexOf(row)]}`);
};

<Table.Row
  key={idList && idList[rowIndex]}
  onClick={() => {
    this.navigateTo(entityName, idList, rows, row);
  }}
  ...

(假设您使用的是客户端路由。如果没有,请使用entityName &amp;&amp; window.location.href = "http://linkToRedirectTo.com"

【讨论】:

    【解决方案2】:

    类似于顶部的答案: [https://codesandbox.io/s/determined-bash-izqsi?file=/src/example.jsx][1]

    【讨论】:

    • 这不起作用,因为在我的情况下它是一个完全不同的链接,它不能使用历史从当前链接创建
    猜你喜欢
    • 1970-01-01
    • 2019-05-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-08-12
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多