正确的减速剂成分

时间:2016-06-07 09:39:14

标签: redux

如何让减速器不再返回新的状态?我的解决方案是否正常还是有更好的方法?

我的状态:

userList: {
    id: 'xxx', // <-|- Not mutable by reducers fields, so using combineReducers for each field is frustrating.
    ba: 'xxx', // <-|
    fo: 'xxx', // <-|
    users: [
        {
            id: 'yyy',
            be: 'yyy',
            fo: 'yyy',
            photo: {
                id: 'zzz',
                url: 'http://image.jpg', <-- The only field, that changes by reducers.
            },
        },
        ...
    ],
}

我目前的减速机:

// Always returns new object.
const userListReducer = (userList, action) => {
    return {
        ...userList,
        users: usersReducer(userList, action),
    }
};

// Always returns new array.
const usersReducer = (users, action) => {
    return users.map(user => userReducer(user, action));
};

// Always returns new object too.
const userReducer = (user, action) => {
    return {
        ...user,
        photo: photoReducer(user.photo, action),
    };
};

// The only one true reducer.
const photoReducer = (photo, action) => {
    switch (action.type) {
        case 'update_photo':
            return {
                ...photo,
                url: action.url,
            };
        default:
            return photo;
    }
};

解决方案

1)。必要时呼叫usersReducer。不好的部分:我们需要关心其他减速器的逻辑。

const userListReducer = (userList, action) => {
    switch (action.type) {
        case 'update_photo':
            return {
                ...userList,
                users: usersReducer(userList, action),
            };
        default:
            return userList;
    }
};

2)。使用combineReducers。不好的部分:我们需要关心所有usersList的形状。此外,这仍然不起作用,因为usersReducer总是返回新数组。

const userListRecuer = combineReducers({
    id: id => id,
    ba: ba => ba,
    fo: fo => fo,
    users: usersReducer,
});

3)。我的解决方案使用mergeOrReturnOld和mapOrReturnOld帮助程序。

const userListReducer = (userList, action) => {
    return mergeOrReturnOld(userList, {
        users: usersReducer(userList, action),
    });
};
const usersReducer = (users, action) => {
    return mapOrReturnOld(users, user => userReducer(user, action));
};
const userReducer = (user, action) => {
    return mergeOrReturnOld(user, {
        photo: photoReducer(user.photo, action),
    });
};

助手实施:

const mergeOrReturnOld = (obj, addition) => {
    let hasChanged = false;

    for (let key in addition) {
        if (addition.hasOwnProperty(key)) {
            if (obj[key] !== addition[key]) {
                hasChanged = true;
            }
        }
    }

    if (!hasChanged) {
        return obj;
    } else {
        return {
            ...obj,
            ...addition,
        };
    }
};

const mapOrReturnOld = (array, callback) => {
    let hasChanged = false;

    const newArray = array.map(item => {
        const newItem = callback(item);

        if (newItem !== item) {
            hasChanged = true;
        }

        return newItem;
    });

    if (!hasChanged) {
        return array;
    } else {
        return newArray;
    }
};

0 个答案:

没有答案