ref为null - 语义UI React Table行

时间:2018-01-16 22:33:43

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

我正在尝试将ref的{​​{1}}传递给点击处理程序。也许我想通过更改className来选择一行并在选中时突出显示它。但是它始终记录为空。

尝试:

Table.row

有人知道为什么<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 } 在这里无法正常工作吗?

2 个答案:

答案 0 :(得分:1)

正如我在评论中提到的,我认为docs中没有对裁判的支持 至于你的ref实现,你在每次迭代时都会覆盖this.row

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

如果要跟踪选择了哪些行,您将需要一个状态中的对象,该对象将在每次单击行(一种查找表对象)时得到更新。

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

为了能够将id传递给Table.Row并作为onClick的参数备份到父级,您可以将Table.Row包裹起来class组件,用于处理点击次数及其返回的数据。

例如,MyRow期望获得rowIdonClick个活动,当然还有我会传递给active的{​​{1}}道具。

点击Table.Row时,它会将MyRow作为参数传递给父级,父级会更新查找表。

以下是此用例的运行示例:

this.props.rowId
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'));

答案 1 :(得分:0)

不是一个非常简单的React-ish解决方案,但非常简单: 而不是使用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>
        );
    }
}