material-uiを使用してthe new Material Design Google Contacts(材料デザインスキンを有効にする必要があります)のように機能する連絡先リストを実装しようとしています。
具体的には、行ホバー上にアバターの代わりにチェックボックスを表示しようとしています。
興味のある行だけをキャッチして再描画して、それに応じてアバター/チェックボックスを表示したいと思っています。これは簡単な作業ですが、レンダリングされた行をレンダリングすることはできません(リスト全体を再レンダリングするのではなく) このようなことをどうやって行うべきか提案はありますか?リスト全体を再レンダリングせずにリストの1行を再描画する
この一時的な解決方法では、テーブルを扱うコンテナコンポーネントが使用されます。 行が移動されると、Table
コンポーネントのonRowHover
から取得し、コンテナ状態で保存します。これにより、リスト全体の再レンダリングがトリガされ、パフォーマンスは非常に悪くなります。
問題のビデオはhereです。ここで
は、コードサンプルです:
import React from 'react'
import Avatar from 'material-ui/lib/avatar'
import Checkbox from 'material-ui/lib/checkbox'
import Table from 'material-ui/lib/table/table'
import TableHeaderColumn from 'material-ui/lib/table/table-header-column'
import TableRow from 'material-ui/lib/table/table-row'
import TableHeader from 'material-ui/lib/table/table-header'
import TableRowColumn from 'material-ui/lib/table/table-row-column'
import TableBody from 'material-ui/lib/table/table-body'
import R from 'ramda'
export default class ContactsList extends React.Component {
constructor (props) {
super(props)
this.state = { hoveredRow: 0 }
this.contacts = require('json!../../public/contacts.json').map((e) => e.user) // Our contact list array
}
_handleRowHover = (hoveredRow) => this.setState({ hoveredRow })
_renderTableRow = ({ hovered, username, email, picture }) => {
const checkBox = <Checkbox style={{ marginLeft: 8 }} />
const avatar = <Avatar src={picture} />
return (
<TableRow key={username}>
<TableRowColumn style={{ width: 24 }}>
{hovered ? checkBox : avatar}
</TableRowColumn>
<TableRowColumn>{username}</TableRowColumn>
<TableRowColumn>{email}</TableRowColumn>
</TableRow>
)
}
render =() =>
<Table
height='800px'
fixedHeader
multiSelectable
onRowHover={this._handleRowHover}
>
<TableHeader displaySelectAll enableSelectAll>
<TableRow>
<TableHeaderColumn>Nome</TableHeaderColumn>
<TableHeaderColumn>Email</TableHeaderColumn>
<TableHeaderColumn>Telefono</TableHeaderColumn>
</TableRow>
</TableHeader>
<TableBody displayRowCheckbox={false} showRowHover>
{this.contacts.map((contact, index) => this._renderTableRow({
hovered: index === this.state.hoveredRow,
...contact }))
}
</TableBody>
</Table>
}
は、事前にありがとうございます。
提案していただきありがとうございます。私たちはすでにこのアプローチを試みましたが、別の問題が発生しています:TableRowとTableは厳密に結びついており、 ReactコンポーネントでTableRowをラップすると、多くのことが壊れます(たとえば、tableRowのホバリングと選択はTableコンポーネントに正しく伝播されません)。 –
@MatteoMazzarolo ok、私はそれを考慮に入れて私の答えを編集しました。この場合、TableBodyコンポーネントが継承しているすべての小道具をTableRowに渡す必要があります。 – VonD
ありがとうございます。 TableBodyの小道具を渡しても正常に動作しないため、行ホバー上のリスト全体の再描画がトリガーされました。 残念ながら、これは時間に敏感な作業ですので、別のレイアウトに切り替えるので、次の日にさらに調査します。 私はあなたの答えがとにかく正しいと判断しています。なぜなら、よりよい解決策はないと思うからです。 私は間違っていると証明されることを願っています:) –