ReactJS - 在不重新渲染的情况下切换可见性
ReactJS - Toggle visibility without re-rendering
我使用 ReactJS + nextJS + Semantic-UI-React
我的 json 回复是这样的。
[
{
"artist": "Cardi B",
"dob": "01/01/1990",
"albums":[
{
"title": "Invasion of privacy",
"year": "2018"
}
],
"country": "usa"
},
{
"artist": "Michael Jackson",
"dob": "01/01/1950",
"albums":[
{
"title": "Thriller",
"year": "1981"
},
{
"title": "Blood On The Dance Floor",
"year": "1995"
}
],
"country": "usa"
}
]
我想在 table 行中显示每个艺术家。单击艺术家行的某个单元格时,将显示艺术家的专辑。
我有两个组成部分。一张给艺术家,一张给专辑。 AlbumTable
组件基本上是包裹在 <Table.Row>
中的另一个 table。基本上下面的代码工作得很好。
toggleVisibility(index){
let oldSt = this.state.AlbumStatus;
oldSt[index] = !oldSt[index];
this.setState({AlbumStatus: oldSt});
}
renderResult(){
let rows = this.props.artists.map((r, index) =>{
return(
<Table.Body key={index}>
<Table.Row >
<Table.Cell>{r.artist}</Table.Cell>
<Table.Cell>{r.dob}</Table.Cell>
<Table.Cell onClick={() => this.toggleVisibility(index)}>+</Table.Cell>
<Table.Cell>{r.country}</Table.Cell>
</Table.Row>
<AlbumRow result={r.albums} hiddenStatus={!this.state.AlbumStatus[index]} />
</Table.Body>
);
});
return rows;
}
render(){
return(
<Table >
<Table.Header >
<Table.Row>
<Table.HeaderCell >Artists</Table.HeaderCell>
<Table.HeaderCell >Dob</Table.HeaderCell>
<Table.HeaderCell >Albums</Table.HeaderCell>
</Table.Row>
</Table.Header>
{this.renderResult()}
</Table>
);
}
我的要求是仅当单击艺术家行的“+”号时才显示专辑。我可以使用上面的代码切换可见性。
问题:
如果我点击'Michael Jackson'行的'+'号,就会显示他对应的相册。然而,所有艺术家的专辑也被重新渲染。这是预期的吗??它会导致大型数据集出现任何性能问题吗?对性能影响不大的最佳方法是什么?
可能不是什么大问题,除非您注意到大型数据集会变得缓慢。在性能方面,如果您认为自己有问题,请先进行测量 (read more on measuring React performance)。不要浪费时间尝试过度优化,直到你知道你有问题。
曾经的建议可能是将每一行分成 PureComponent
:
import React, { PureComponent } 'react';
class AlbumTableRow extends PureComponent {
render() {
const {
key,
artist,
dob,
country
albums,
albumsHiddenStatus,
onToggleVisibility,
} = this.props;
return(
<Table.Body key={key}>
<Table.Row >
<Table.Cell>{artist}</Table.Cell>
<Table.Cell>{dob}</Table.Cell>
<Table.Cell onClick={onToggleVisibility}>+</Table.Cell>
<Table.Cell>{country}</Table.Cell>
</Table.Row>
<AlbumRow result={albums} hiddenStatus={albumsHiddenStatus} />
</Table.Body>
);
}
}
export default AlbumTableRow;
PureComponents 应该 仅在 prop values 更改时重新渲染。然后,您应该像这样更改父组件代码:
getOnToggleVisibility = (index) => () => this.toggleVisibility(index);
renderResult(){
let rows = this.props.artists.map((r, index) =>{
return (
<AlbumTableRow
key={index}
artist={r.artist}
dob={r.dob}
country={r.country}
albums={r.albums}
albumsHiddenStatus={!this.state.AlbumStatus[index]}
onToggleVisibility={this.getOnToggleVisibility(index)}
/>
);
});
return rows;
}
请注意,我添加了一个 getOnToggleVisibility
方法,该方法采用该索引和 returns 一个知道要使用的正确索引的 onToggleVisibility
函数。
我使用 ReactJS + nextJS + Semantic-UI-React
我的 json 回复是这样的。
[
{
"artist": "Cardi B",
"dob": "01/01/1990",
"albums":[
{
"title": "Invasion of privacy",
"year": "2018"
}
],
"country": "usa"
},
{
"artist": "Michael Jackson",
"dob": "01/01/1950",
"albums":[
{
"title": "Thriller",
"year": "1981"
},
{
"title": "Blood On The Dance Floor",
"year": "1995"
}
],
"country": "usa"
}
]
我想在 table 行中显示每个艺术家。单击艺术家行的某个单元格时,将显示艺术家的专辑。
我有两个组成部分。一张给艺术家,一张给专辑。 AlbumTable
组件基本上是包裹在 <Table.Row>
中的另一个 table。基本上下面的代码工作得很好。
toggleVisibility(index){
let oldSt = this.state.AlbumStatus;
oldSt[index] = !oldSt[index];
this.setState({AlbumStatus: oldSt});
}
renderResult(){
let rows = this.props.artists.map((r, index) =>{
return(
<Table.Body key={index}>
<Table.Row >
<Table.Cell>{r.artist}</Table.Cell>
<Table.Cell>{r.dob}</Table.Cell>
<Table.Cell onClick={() => this.toggleVisibility(index)}>+</Table.Cell>
<Table.Cell>{r.country}</Table.Cell>
</Table.Row>
<AlbumRow result={r.albums} hiddenStatus={!this.state.AlbumStatus[index]} />
</Table.Body>
);
});
return rows;
}
render(){
return(
<Table >
<Table.Header >
<Table.Row>
<Table.HeaderCell >Artists</Table.HeaderCell>
<Table.HeaderCell >Dob</Table.HeaderCell>
<Table.HeaderCell >Albums</Table.HeaderCell>
</Table.Row>
</Table.Header>
{this.renderResult()}
</Table>
);
}
我的要求是仅当单击艺术家行的“+”号时才显示专辑。我可以使用上面的代码切换可见性。
问题:
如果我点击'Michael Jackson'行的'+'号,就会显示他对应的相册。然而,所有艺术家的专辑也被重新渲染。这是预期的吗??它会导致大型数据集出现任何性能问题吗?对性能影响不大的最佳方法是什么?
可能不是什么大问题,除非您注意到大型数据集会变得缓慢。在性能方面,如果您认为自己有问题,请先进行测量 (read more on measuring React performance)。不要浪费时间尝试过度优化,直到你知道你有问题。
曾经的建议可能是将每一行分成 PureComponent
:
import React, { PureComponent } 'react';
class AlbumTableRow extends PureComponent {
render() {
const {
key,
artist,
dob,
country
albums,
albumsHiddenStatus,
onToggleVisibility,
} = this.props;
return(
<Table.Body key={key}>
<Table.Row >
<Table.Cell>{artist}</Table.Cell>
<Table.Cell>{dob}</Table.Cell>
<Table.Cell onClick={onToggleVisibility}>+</Table.Cell>
<Table.Cell>{country}</Table.Cell>
</Table.Row>
<AlbumRow result={albums} hiddenStatus={albumsHiddenStatus} />
</Table.Body>
);
}
}
export default AlbumTableRow;
PureComponents 应该 仅在 prop values 更改时重新渲染。然后,您应该像这样更改父组件代码:
getOnToggleVisibility = (index) => () => this.toggleVisibility(index);
renderResult(){
let rows = this.props.artists.map((r, index) =>{
return (
<AlbumTableRow
key={index}
artist={r.artist}
dob={r.dob}
country={r.country}
albums={r.albums}
albumsHiddenStatus={!this.state.AlbumStatus[index]}
onToggleVisibility={this.getOnToggleVisibility(index)}
/>
);
});
return rows;
}
请注意,我添加了一个 getOnToggleVisibility
方法,该方法采用该索引和 returns 一个知道要使用的正确索引的 onToggleVisibility
函数。