ref 为 null - 语义 UI 反应 Table 行
ref is null - Semantic UI React Table row
我正在尝试将 Table.row
的 ref
传递到点击处理程序中。也许我想 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>
);
}
}
我正在尝试将 Table.row
的 ref
传递到点击处理程序中。也许我想 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>
);
}
}