即使对象相同,React- Lodash的isEqual返回false

问题描述

我正在尝试通过使用React Memo防止我的子组件重新呈现。但是,由于react memo使用浅层比较,因此我尝试引入lodash _.isEqual方法以进行深层比较,以防止在对象的值不变时重新渲染。但是,即使对象的值没有变化,它也会返回false。有什么原因吗?如果对象比较不同时比较浅,我会明白,但是为什么深层比较返回false?

这是我的代码

import React,{ useState } from 'react'
import { Button,Empty,List,Spin,Menu,Dropdown,Skeleton } from 'antd';
import OpportunityDrawer from './Forms/OpportunityDrawer';
import { FileImageOutlined,MoreOutlined,MailOutlined,IdcardOutlined } from '@ant-design/icons';
import { useSelector } from 'react-redux'
import RequirementHistory from './RequirementHistory';

const _ = require("lodash");

function RequirementTimeline({ requirements }) {


    const actions = (requirement) => (
        <Menu>
            <Menu.Item>
                <OpportunityDrawer data={requirement}
                    button_name='Edit Requirement'
                    title='Edit Requirement'
                    component='RequirementUpdate'
                    button_type='update' />
            </Menu.Item>
            <Menu.Item><OpportunityDrawer data={requirement.customer_requirement_id}
                button_name='Delete Requirement'
                title='Delete Requirement'
                component='RequirementDelete'
                button_type='delete' /></Menu.Item>
            {requirement.file ?
                <Menu.Item>
                    <Button type="text" shape="circle" size="small"><a href={requirement.file}><FileImageOutlined /></a></Button> File
                </Menu.Item>
                : null}
            <Menu.Item><RequirementHistory history={requirement.history} /></Menu.Item>
            <Menu.Item><CalendarDrawer
                button_name='Create Reminder'
                title='When Shall we remind you?'
                component='CreateReminder'
                task_title={`Reminder [Requirements ID: ${requirement.customer_requirement_id}]`}
                content={`Please remember to follow up on Requirement [${requirement.customer_requirement_id}]`}
            />
            </Menu.Item>
        </Menu>
    )

    console.log('hi')

    return (
        requirements.length ?
            <List
                size="large"
                dataSource={requirements}
                renderItem={item => (
                    <List.Item>
                        <div className='requirement-grid'>
                            <p className='requirement-title'><MailOutlined />{item.requirements}</p>
                            <p className='requirement-description'><IdcardOutlined /> ID: {item.customer_requirement_id}</p>
                            <Dropdown placement="bottomRight" overlay={() => actions(item)}>
                                <Button size='small' shape='circle' className='requirement-button'><MoreOutlined /></Button>
                            </Dropdown>
                        </div>
                    </List.Item>
                )}
            />
            : <Empty image={Empty.PRESENTED_IMAGE_SIMPLE} />
    )
}

export default React.memo(RequirementTimeline,(prevProps,nextProps) => {
        console.log(_.isEqual(prevProps.requirements,nextProps.requirements));
        return _.isEqual(prevProps.requirements,nextProps.requirements)
    })

从本质上讲,需求道具的内容不会改变。在父组件中,数据会更改,但是作为数据一部分的嵌套对象“ requirement”不会更改。

例如,我所做的是更新了另一部分数据,同时保留了“要求”的内容。

{ project_name: /* this is changed */,requirements: [ /* this is not changed */
}

^请注意,当我说“此内容未更改”时,我指的是内容,而不是引用,因为我确实理解该引用已更改,因为在更改“ project_name”以达到该目标后会进行新的api调用要存储的新数据。但是,由于'requirements'的内容未更改,因此对于lodash的_.isEqual方法,它是否应该评估为true?

我正在使用React Memo。请告知是否有更好的方法来防止重新渲染。我知道深度比较的成本很高,但是我需要防止不必要地重新渲染子组件,因为这会影响性能并导致网站变慢。理想情况下,我只想重新呈现那些已更改的数据部分。

解决方法

道具会有所不同,因为有些标识符在更新时会发生变化。通常用于比较上一个和下一个道具,并防止更快地进行其他渲染。

您是否可以包含其他财产?喜欢比较prevProps.requirements.id还是使用钩子让您选择反应?

在记录下一个和上一个道具时,您会发现它们不相等,或者在调用JSON.stringify之后记录它们,

我还将重新考虑需要React.memo。 React已经非常擅长于此,并且可以添加更多东西。

相关问答

错误1:Request method ‘DELETE‘ not supported 错误还原:...
错误1:启动docker镜像时报错:Error response from daemon:...
错误1:private field ‘xxx‘ is never assigned 按Alt...
报错如下,通过源不能下载,最后警告pip需升级版本 Requirem...