当前位置: 首页 > 工具软件 > immer > 使用案例 >

immer简易实现

公西宏峻
2023-12-01
const isObject = target => typeof target === 'object' && target !== null;

const produce = (target, action) => {
    const copy = Array.isArray(target) ? [...target] : {...target};
    let temp = copy;
    const handler = {
        get(target, key) {
            const value = temp[key];

            if (Array.isArray(target)) {
                if (typeof target[key] === 'function') {
                    return value.bind(temp);
                } else if (key === 'length') {
                    return value;
                }
            }

            // 自上而下逐层浅拷贝
            temp[key] = isObject(value) 
                ? Array.isArray(value) 
                    ? [...value] 
                    : {...value} 
                : value;
            temp = temp[key];

            if (isObject(value)) {
                return new Proxy(value, handler);
            }
            return value;
        },
        set(target, key, value) {
            temp[key] = value;
            temp = copy;
            return true;
        },
        deleteProperty(target, key) {
            delete temp[key];
            temp = copy;
            return true;
        }
    };
    const proxy = new Proxy(target, handler);
    action(proxy);
    return copy;
};


const arr = [1, 2, 3, {a: {b: 2, d: 1}, c: {}}];

const clone = produce(arr, draft => {
    draft[2] = 2;
    draft.shift();
    draft.push(4);
    draft[2].a.b = 'b';
    delete draft[2].a.d;
});

// clone: [2,2,{"a":{"b":"b"},"c":{}},4]
// clone[2].c === arr[3].c : true

 类似资料: