Javascript 如何避免在React中的嵌套列表中重新渲染
我有分层的、递归的数据结构。它是一个命名项目的列表,每个项目都可以有自己的子项目列表。看起来是这样的:Javascript 如何避免在React中的嵌套列表中重新渲染,javascript,reactjs,Javascript,Reactjs,我有分层的、递归的数据结构。它是一个命名项目的列表,每个项目都可以有自己的子项目列表。看起来是这样的: const items = [ { name: 'item1', items: [ {name: 'item2'}, {name: 'item3'}, {name: 'item4', items: [ { nam
const items = [
{
name: 'item1',
items: [
{name: 'item2'},
{name: 'item3'},
{name: 'item4', items: [
{
name: 'item5'
}
]},
]
},
{
name: 'item6'
}
]
class App extends Component {
constructor() {
super(...arguments)
this.state = {
items: items,
highlightedItemsNames: {},
}
this.handleHighligtItem = (item) => {
this.setState({highlightedItemsNames: {
...this.state.highlightedItemsNames, [item.name]: true
}})
}
this.handleDehighlightAllItems = () => {
this.setState({highlightedItemsNames: {}})
}
}
render() {
return <div>
<button onClick={this.handleDehighlightAllItems}>dehighlight</button>
<List
items={this.state.items}
highlightedItemsNames={this.state.highlightedItemsNames}
onHighlight={this.handleHighligtItem}
/>
</div>
}
}
function List(props) {
return <ul>
{props.items.map(item => <li key={item.name}>
<Item
item={item}
highlighted={props.highlightedItemsNames[item.name]}
highlightedItemsNames={props.highlightedItemsNames}
onHighlight={props.onHighlight}
/>
</li>)}
</ul>
}
function Item(props) {
let className = "item"
if (props.highlighted) {
className += '-highlighted'
}
console.log('renders item', props.item.name)
return <div>
<span className={className}>{props.item.name}</span>
<button onClick={() => props.onHighlight(props.item)}>highlight</button>
{props.item.items ? <List
items={props.item.items}
highlightedItemsNames={props.highlightedItemsNames}
onHighlight={props.onHighlight}
/> : null}
</div>
}
我想用嵌套的子列表在无序列表中显示它。此外,我还需要能够标记为突出显示的一些项目,并取消所有项目的高光。由于第二个需求,关于突出显示项的信息必须存在于顶级组件中
我的天真实现如下所示:
const items = [
{
name: 'item1',
items: [
{name: 'item2'},
{name: 'item3'},
{name: 'item4', items: [
{
name: 'item5'
}
]},
]
},
{
name: 'item6'
}
]
class App extends Component {
constructor() {
super(...arguments)
this.state = {
items: items,
highlightedItemsNames: {},
}
this.handleHighligtItem = (item) => {
this.setState({highlightedItemsNames: {
...this.state.highlightedItemsNames, [item.name]: true
}})
}
this.handleDehighlightAllItems = () => {
this.setState({highlightedItemsNames: {}})
}
}
render() {
return <div>
<button onClick={this.handleDehighlightAllItems}>dehighlight</button>
<List
items={this.state.items}
highlightedItemsNames={this.state.highlightedItemsNames}
onHighlight={this.handleHighligtItem}
/>
</div>
}
}
function List(props) {
return <ul>
{props.items.map(item => <li key={item.name}>
<Item
item={item}
highlighted={props.highlightedItemsNames[item.name]}
highlightedItemsNames={props.highlightedItemsNames}
onHighlight={props.onHighlight}
/>
</li>)}
</ul>
}
function Item(props) {
let className = "item"
if (props.highlighted) {
className += '-highlighted'
}
console.log('renders item', props.item.name)
return <div>
<span className={className}>{props.item.name}</span>
<button onClick={() => props.onHighlight(props.item)}>highlight</button>
{props.item.items ? <List
items={props.item.items}
highlightedItemsNames={props.highlightedItemsNames}
onHighlight={props.onHighlight}
/> : null}
</div>
}
类应用程序扩展组件{
构造函数(){
超级(…参数)
此.state={
项目:项目,,
highlightedItemsNames:{},
}
this.handleHighligtItem=(项目)=>{
此.setState({highlighteditemsname:{
…this.state.highlightedItemsNames,[item.name]:true
}})
}
this.handleDehighlightAllItems=()=>{
this.setState({highlightedItemsNames:{}})
}
}
render(){
返回
脱光
}
}
功能列表(道具){
返回
{props.items.map(item=>-
)}
}
功能项目(道具){
让className=“item”
如果(突出显示的道具){
className+='-突出显示'
}
console.log('renders item',props.item.name)
返回
{props.item.name}
props.onHighlight(props.item)}>highlight
{props.item.items?:null}
}
但现在,当我突出显示一个项目时,highlightedItemsNames
会发生变化,并且每个项目都会重新呈现。要正确显示数据,只需重新渲染高亮显示的项及其父项。那么,如何避免所有这些不必要的重新渲染呢
在我的应用程序中,项目列表可能有点大,重新呈现所有项目会导致应用程序在单击时明显冻结
我可以在Item
中实现shoulldcomponentupdate
,检查是否应该重新呈现任何子项,但这是否有实际机会提高虚拟dom的性能
我没有使用Redux或任何其他状态管理库,现在我不想这样做。ShouldComponentUpdate
用于检查和决定是否需要重新渲染。显然,在不必要地重新渲染大型项目的情况下执行此操作是明智的决定。我想你应该试着实施这个活动,看看它的表现。我相信尝试是让大多数事情变得完美的原因。您需要为元素设置唯一的键。否则它将始终重新渲染。请检查此项:@MuratK。物品名称是唯一的-所以我在@FabioAntunes的上有唯一的道具,我没有使用Redux