Photo rating function
There's a few things you can do and different approaches depending on your personal preference. You could:

Extract the cases to pure functions

Extracting the logic to methods could help with readability and ease testing.

const addPicture = (state, action) =&gt; [
  {
    id: action.id,
    picture: action.picture,
    votes: 0,
  },
  ...state,
]

const likeUpPicture = (state, action) =&gt;
  state.map(picture =&gt; {
    if (picture.id === action.id) {
      return {
        ...picture,
        votes: picture.votes + 1,
      }
    }

    return picture
  })

const likeDownPicture = (state, action) =&gt;
  state.map(picture =&gt; {
    if (picture.id === action.id) {
      return {
        ...picture,
        votes: picture.votes - 1,
      }
    }

    return picture
  })

const pictures = (state = [], action) =&gt; {
  switch (action.type) {
    case ADD_PICTURE:
      return addPicture(state, action);
    case LIKE_UP_PICTURE:
      return likeUpPicture(state, action);
    case LIKE_DOWN_PICTURE:
      return likeDownPicture(state, action);
  }
}


Object destructuring/Object shorthand

Destructuring parameters could help signal that from a given action we are only concerned with certain properties. Shorthand notation can help keep the functions concise and reduce duplication.

const addPicture = (state, { id, picture }) =&gt; [
  {
    id,
    picture,
    votes: 0,
  },
  ...state,
]

const likeUpPicture = (state, { id }) =&gt;
  state.map(picture =&gt; {
    if (picture.id === id) {
      return {
        ...picture,
        votes: picture.votes + 1,
      }
    }

    return picture
  })

const likeDownPicture = (state, { id }) =&gt;
  state.map(picture =&gt; {
    if (picture.id === id) {
      return {
        ...picture,
        votes: picture.votes - 1,
      }
    }

    return picture
  })


Extract common logic

Since updating a certain element given an id is a common operation extracting the logic to a method might help reduce duplication and increase readability.

const updatePicture = (pictures, predicate, callback) =&gt;
  pictures.map(picture =&gt; predicate(picture) ? callback(picture) : picture)

const likeUpPicture = (state, action) =&gt;
  updatePicture(state, picture =&gt; picture.id === action.id, picture =&gt; ({
    ...picture,
    votes: picture.votes + 1,
  }))

const likeDownPicture = (state, action) =&gt;
  updatePicture(pictures, picture =&gt; picture.id === action.id, picture =&gt; ({
    ...picture,
    votes: picture.votes - 1,
  }))


Define your reducer another way

For example, using createReducer can result in a compact reducer definition

const initialState = []

const pictures = createReducer(initialState, {
  [ADD_PICTURE]: addPicture,
  [LIKE_UP_PICTURE]: likeUpPicture,
  [LIKE_DOWN_PICTURE]: likeDownPicture,
})


Normalize State Shape

I've defined the methods inline for brevity but you could extract them as above. The official Redux link above gives a good explanation on why you might want to consider normalizing your state shape.

const byId = createReducer({}, {
  [ADD_PICTURE]: (state, { id, picture }) =&gt; ({
    ...state,
    [id]: {
      ...picture,
      id,
      votes: 0,
    }
  }),

  [LIKE_UP_PICTURE]: (state, { id }) =&gt; ({
    ...state,
    [id]: {
      ...state[id],
      votes: state[id].votes + 1,
    },
  }),

  [LIKE_DOWN_PICTURE]: (state, { id }) =&gt; ({
    ...state,
    [id]: {
      ...state[id],
      votes: state[id].votes - 1,
    }
  })
})

const allIds = createReducer([], {
  [ADD_PICTURE]: (state, { id }) =&gt; [
    ...state,
    id,
  ],
})

const pictures = combineReducers({
  allIds,
  byIds,
})