MST
星途 面试题库

面试题:React componentDidUpdate 性能优化与深层对象比较

假设在 componentDidUpdate 中有一个深层嵌套的对象作为依赖,如何有效地比较这个对象的变化,以避免不必要的更新操作?请阐述实现思路并给出代码示例。
19.0万 热度难度
前端开发React

知识考点

AI 面试

面试题答案

一键面试

实现思路

  1. 浅比较:使用 Object.is() 或者 lodashisEqual 进行浅层比较,但是对于深层嵌套对象,这种方式不能完全满足需求。
  2. 深度比较:可以自己实现深度比较函数或者使用 lodashisDeepEqual 方法。深度比较函数需要递归检查对象的每一个属性和子对象,确保所有层级的属性都被比较。

代码示例

  1. 使用原生 JavaScript 实现深度比较
function deepCompare(obj1, obj2) {
    if (obj1 === obj2) return true;
    if (typeof obj1!== 'object' || obj1 === null || typeof obj2!== 'object' || obj2 === null) return false;

    const keys1 = Object.keys(obj1);
    const keys2 = Object.keys(obj2);

    if (keys1.length!== keys2.length) return false;

    for (let key of keys1) {
        if (!keys2.includes(key) ||!deepCompare(obj1[key], obj2[key])) return false;
    }

    return true;
}

class MyComponent extends React.Component {
    constructor(props) {
        super(props);
        this.state = {
            deepObject: {
                a: {
                    b: {
                        c: 'initial value'
                    }
                }
            }
        };
    }

    componentDidUpdate(prevProps, prevState) {
        if (!deepCompare(prevState.deepObject, this.state.deepObject)) {
            // 只有当对象有实际变化时才执行更新操作
            console.log('Object has changed, perform update');
        }
    }

    handleClick = () => {
        this.setState(prevState => {
            return {
                deepObject: {
                   ...prevState.deepObject,
                    a: {
                       ...prevState.deepObject.a,
                        b: {
                           ...prevState.deepObject.a.b,
                            c: 'new value'
                        }
                    }
                }
            };
        });
    }

    render() {
        return (
            <div>
                <button onClick={this.handleClick}>Update Object</button>
            </div>
        );
    }
}
  1. 使用 lodash 的 isDeepEqual 首先需要安装 lodashnpm install lodash
import React from'react';
import { isDeepEqual } from 'lodash';

class MyComponent extends React.Component {
    constructor(props) {
        super(props);
        this.state = {
            deepObject: {
                a: {
                    b: {
                        c: 'initial value'
                    }
                }
            }
        };
    }

    componentDidUpdate(prevProps, prevState) {
        if (!isDeepEqual(prevState.deepObject, this.state.deepObject)) {
            // 只有当对象有实际变化时才执行更新操作
            console.log('Object has changed, perform update');
        }
    }

    handleClick = () => {
        this.setState(prevState => {
            return {
                deepObject: {
                   ...prevState.deepObject,
                    a: {
                       ...prevState.deepObject.a,
                        b: {
                           ...prevState.deepObject.a.b,
                            c: 'new value'
                        }
                    }
                }
            };
        });
    }

    render() {
        return (
            <div>
                <button onClick={this.handleClick}>Update Object</button>
            </div>
        );
    }
}