将项目添加到列表后如何避免重新渲染?
Posted
技术标签:
【中文标题】将项目添加到列表后如何避免重新渲染?【英文标题】:How to avoid re-render after i've added and Item to the list? 【发布时间】:2021-05-08 06:18:39 【问题描述】:我有一个需要更新的功能组件。
export const VendorCategory = (setShowProgress, user) =>
const classes = useStyles()
const theme = useTheme()
const listElements = []
const [dummyCategory, setDummyCategory] = useState(
"Test1": [
"Subtest1", "Subtest2", "Subtest3"
],
"Test2": [
"Subtest1", "Subtest2", "Subtest3"
],
"Test3": [
"Subtest1", "Subtest2", "Subtest3"
]
)
useEffect(() =>
return () =>
console.log("re-rendered")
)
const AddSubCategory = useCallback(() =>
setShowProgress(true)
const newAdd = dummyCategory['Test1']
newAdd.push("SubTest4")
setDummyCategory(...dummyCategory, "Test1": newAdd)
setShowProgress(false)
,[setShowProgress,setDummyCategory,dummyCategory])
return (
<div className=classes.root>
<h3 className=classes.title>Vendor Category</h3>
<Button
className=classes.button
variant='contained'
color="primary"
>
Add Category
</Button>
<div className=classes.categoryDiv>
Object.keys(dummyCategory).map((value, index) =>
return (
<List>
<Accordion key=uuid() mt=2>
<AccordionSummary
expandIcon=<ExpandMoreIcon/>
aria-controls="panel1a-content"
id="panel1a-header"
>
<ListSubheader key=uuid() className=classes.sublistHeader component="div"
id="nested-list-subheader">
value
</ListSubheader>
</AccordionSummary>
<AccordionDetails className=classes.subCategoryList>
<Button
className=classes.button
variant='contained'
color="primary"
onClick=AddSubCategory
>
Add Sub-Category
</Button>
dummyCategory[value].map((subvalue, index) =>
return (
<ListItem button key=subvalue>
<ListItemText inset primary=subvalue/>
</ListItem>
)
)
</AccordionDetails>
</Accordion>
</List>)
)
</div>
</div>
)
const mapStateToProps = (state) => (
user: state.user
)
const mapDispatchToProps =
export default connect(mapStateToProps, mapDispatchToProps)(VendorCategory)
问题是每次我向其添加项目时,手风琴都会重新渲染,然后折叠。 如何阻止它由于重新渲染而崩溃?UseCallback 钩子也会重新渲染。我如何使用 React.Memo 来避免这种情况? 或者在这种情况下如何使用 useEffect 。同样,我需要在手风琴不折叠的情况下添加一个项目。可能吗? 任何帮助将不胜感激。
【问题讨论】:
难道您没有可以在手风琴上设置的选项来定义其状态(打开/关闭)吗? 如果您的手风琴正在崩溃,那么问题不在于它正在重新渲染,而在于它正在重新安装。最可能的原因是您没有使用稳定的键 -key=uuid()
将在每次渲染时生成一个新键,因此 React 认为它是一个新组件。键应该是唯一的,并且在组件的生命周期内永远不会改变。
这是一个很好的建议...我会试一试并回复您。 :)
请回复上述声明,以便我给你一个赞。你为我节省了很多研究:)
【参考方案1】:
React.memo 避免了重新渲染。在您的 Accordion 函数中,尝试:
import memo from 'react';
const Accordion = (props) =>
//your code
;
export default memo(Accordion);
【讨论】:
【参考方案2】:根据 cmets,映射的 React 元素应该被赋予唯一、稳定的键,这些键在元素的整个生命周期中都存在。当一个键改变时,就 React 而言,一个新的组件就被挂载了。
在key=uuid()
或onClick=handleClick()
等元素或组件上内联调用的函数将在每次渲染 上调用。在这种情况下,内联调用 uuid()
会为父组件的每个渲染生成一个新键,从而导致重新安装映射的子组件。
【讨论】:
以上是关于将项目添加到列表后如何避免重新渲染?的主要内容,如果未能解决你的问题,请参考以下文章
Power Query:当特定值出现在另一列中时如何将一个添加到列中
如何避免在反应功能组件中对“静态组件”进行不必要的重新渲染?