ref 为 null - 语义 UI 反应 Table 行

ref is null - Semantic UI React Table row

我正在尝试将 Table.rowref 传递到点击处理程序中。也许我想 select 一行并在 selected 时通过更改类名突出显示它。但是它总是记录 null.

尝试:

<Table.Body>
    {_.map(data, ({ Name, Version, Type, Modified }) => (
        <Table.Row
          ref={(ref) => { this.row = ref; }}
          className=""
          key={Version}
          onClick={() => this.handleClick(this.row, Name, Version, Type, Modified)}
        >
            <Table.Cell>{Name}</Table.Cell>
            <Table.Cell>{Version}</Table.Cell>
            <Table.Cell>{Type}</Table.Cell>
            <Table.Cell>{Modified}</Table.Cell>
        </Table.Row>
    ))}
</Table.Body>

handleClick(row, Name, Version, Type, Modified) {
    const me = this;
    log.info('logging row', row); //null
    log.info('logging row data', Name, Version, Type, Modified); //works
}

有人知道为什么 ref 在这里不能正常工作吗?

正如我在评论中提到的,我在他们的 docs.
中没有看到任何对 refs 的支持 至于您的 ref 实现,您将在每次迭代中覆盖 this.row

无论如何,在我看来,对此有一个更加反应式的解决方案。

如果您想跟踪选择了哪些行,您将需要一个处于您状态的对象,该对象将在每次单击行时更新,一种查找 table 对象。

要创建这样的查找 table,您将需要每一行的 ID(您可以使用数据对象中的 ID 或数组的索引)。

为了能够将 id 传递给 Table.Row 并作为 onClick 的参数返回给父级,您可以包装 Table.Row使用一个 class 组件来处理点击和它 returns 的数据。

例如 MyRow 将期望得到一个 rowId,一个 onClick 事件,当然还有我们将传递给 [=14= 的 active 道具].

MyRow 被点击时,它会将 this.props.rowId 作为参数传递给父级,父级将更新查找 table.

这是此用例的 运行 示例:

const { Table } = semanticUIReact; // --> import { Table } from 'semantic-ui-react'

const usersFromServer = [
  { name: 'john', age: 25, gender: 'male', id: 1 },
  { name: 'jane', age: 22, gender: 'female', id: 2 },
  { name: 'david', age: 31, gender: 'male', id: 3 },
  { name: 'jain', age: 29, gender: 'female', id: 4 }
];


class MyRow extends React.Component {
  onClick = (e) => {
    const { onClick, rowId } = this.props;
    onClick(rowId, e);
  }

  render() {
    const { data, active } = this.props;
    return (
      <Table.Row onClick={this.onClick} active={active}>
        <Table.Cell>{data.name}</Table.Cell>
        <Table.Cell>{data.age}</Table.Cell>
        <Table.Cell >{data.gender}</Table.Cell>
      </Table.Row>
    );
  }
}


class TableExample extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      activeRows: []
    }
  }

  onRowClick = (id, e) => {
    const { activeRows } = this.state;
    const nextRows = {
      ...activeRows,
      [id]: !activeRows[id]
    }
    this.setState({ activeRows: nextRows });
  }

  render() {
    const { activeRows } = this.state;
    return (
      <Table unstackable>
        <Table.Header>
          <Table.Row>
            <Table.HeaderCell>Name</Table.HeaderCell>
            <Table.HeaderCell>Age</Table.HeaderCell>
            <Table.HeaderCell>Gender</Table.HeaderCell>
          </Table.Row>
        </Table.Header>

        <Table.Body>
          {
            usersFromServer.map((u) => {
              const isActive = activeRows[u.id];
              return (
                <MyRow
                  active={isActive}
                  key={u.id}
                  rowId={u.id}
                  data={u}
                  onClick={this.onRowClick}
                />
              );
            })
          }

        </Table.Body>
      </Table>
    )
  }
}

ReactDOM.render(<TableExample />, document.getElementById('root'));
<link href="https://cdnjs.cloudflare.com/ajax/libs/semantic-ui/2.2.9/semantic.min.css" rel="stylesheet"/>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/semantic-ui-react@0.77.2/dist/umd/semantic-ui-react.min.js"></script>
<div id="root"></div>

不是一个非常 React 式的解决方案,但非常简单: 我没有使用 refs 为每一行创建一个唯一的 id。然后在 clickHandler 中我可以识别该行并将其标记为选中:

export default class TableExampleSortable extends Component {

    constructor(props) {
        super(props);

        this.state = {
            column: null,
            data: props.convo,
            direction: null,
        };

        this.handleClick = this.handleClick.bind(this);
    }


    handleSort = clickedColumn => () => {
        const { column, data, direction } = this.state;

        if (column !== clickedColumn) {
            this.setState({
                column: clickedColumn,
                data: _.sortBy(data, [clickedColumn]),
                direction: 'ascending',
            });

            return;
        }

        this.setState({
            data: data.reverse(),
            direction: direction === 'ascending' ? 'descending' : 'ascending',
        });
    }

    handleClick(Version) {
        const element = document.getElementById(Version);
        if (element.className === 'selected') {
            element.className = 'notSelected';
        } else {
            element.className = 'selected';
        }
    }

    render() {
        const { column, data, direction } = this.state;

        return (
            <div>
                <Table sortable selectable>
                    <Table.Header>
                        <Table.Row>
                            <Table.HeaderCell sorted={column === 'Name' ? direction : null} onClick={this.handleSort('Name')}>
                                Name
                            </Table.HeaderCell>
                            <Table.HeaderCell sorted={column === 'Version' ? direction : null} onClick={this.handleSort('Version')}>
                                Version
                            </Table.HeaderCell>
                            <Table.HeaderCell sorted={column === 'Type' ? direction : null} onClick={this.handleSort('Type')}>
                                Type
                            </Table.HeaderCell>
                            <Table.HeaderCell sorted={column === 'Modified' ? direction : null} onClick={this.handleSort('Modified')}>
                                Modified
                            </Table.HeaderCell>
                        </Table.Row>
                    </Table.Header>
                    <Table.Body>
                        {_.map(data, ({ Name, Version, Type, Modified }) => (
                            <Table.Row
                              id={Version}
                              className="notSelected"
                              key={Version}
                              onClick={() => this.handleClick(Version)}
                            >
                                <Table.Cell>{Name}</Table.Cell>
                                <Table.Cell>{Version}</Table.Cell>
                                <Table.Cell>{Type}</Table.Cell>
                                <Table.Cell>{Modified}</Table.Cell>
                            </Table.Row>
                        ))}
                    </Table.Body>
                </Table>
            </div>
        );
    }
}