immerjs / immer

Create the next immutable state by mutating the current one
https://immerjs.github.io/immer/
MIT License
27.66k stars 848 forks source link

[Question]Maybe the README example could be adjusted a little #57

Closed NE-SmallTown closed 6 years ago

NE-SmallTown commented 6 years ago
// Plain reducer
function insertItem(array, action) {
    return [
        ...array.slice(0, action.index),
        action.item,
        ...array.slice(action.index)
    ]
}

--------------------------- I think the more real world way is: 
function insertItem(array, action) {
    return array.slice().splice(action.index, 0, action.item)
}

// With immer
function insertItem(array, action) {
    return produce(array, draft => {
        draft.splice(action.index, 0, action.item)
    })
}

// Plain reducer
function removeItem(array, action) {
    return [
        ...array.slice(0, action.index),
        ...array.slice(action.index + 1)
    ];
}

--------------------------- I think the more real world way is: 
function removeItem(array, action) {
    return array.slice().splice(action.index, 1)
}

// With immer
function removeItem(array, action) {
    return produce(array, draft => {
        draft.splice(action.index, 1)
    })
}

// Plain reducer
function updateObjectInArray(array, action) {
    return array.map( (item, index) => {
        if(index !== action.index) {
            // This isn't the item we care about - keep it as-is
            return item;
        }

        // Otherwise, this is the one we want - return an updated value
        return {
            ...item,
            ...action.item
        };
    });
}

--------------------------- I think the more real world way is just updateObject:
function updateObject(foosMap, action) {
   return {
      [action.item.id]: {
        ...foosMap[action.item.id],
        ...action.item
      }
   }

  // or more accurate (assume we just want to update bar)
  return lodash.merge({}, foosMap[action.item.id], {bar: action.bar})
}
because in most cases we will convert objectArray to object by using normalizr or something else

// With immer
function updateObjectInArray(array, action) {
    return produce(array, draft => {
        draft[action.index] = { ...item, ...action.item}
        // Alternatively, since arbitrarily deep updates are supported:
        // Object.assign(draft[action.index], action.item)
    })
}
mweststrate commented 6 years ago

I think the whole section could be dropped. Doesn't really add any value, one good example suffices better than 5 contrived ones.