【问题标题】: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 认为它是一个新组件。键应该是唯一的,并且在组件的生命周期内永远不会改变。
  • 这是一个很好的建议...我会试一试并回复您。 :)
  • 请回复上述声明,以便我给你一个赞。你为我节省了很多研究:)

标签: reactjs react-redux react-functional-component


【解决方案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() 会为父组件的每个渲染生成一个新键,从而导致重新安装映射的子组件。

    【讨论】:

      猜你喜欢
      • 2020-03-02
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-11-12
      • 2016-12-06
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多