javascript - 如何以不可变的方式更新数组

标签 javascript arrays reactjs redux immutability


麻烦!请帮助。我将非常感激!
在这个对象中,我应该以不可变的方式仅更新注释数组(所有这些都只是模拟数据,无关紧要):

const initialState = {
  news: [
    {
      id: 1,
      text: 'Hello!',
      createdBy: '',
      comments: [{ id: 0, author: 0, commentText: 0 }]
    },
    {
      id: 2,
      text: 'TEST',
      createdBy: '',
      comments: [{ id: 11, author: 11, commentText: 11 }, { id: 12, author: 12, commentText: 12 }]
    },
    {
      id: 3,
      text: 'TEXT:)',
      createdBy: '',
      comments: []
    }
  ]
}

而且真的很难...我尝试了很多变体,但都不成功...(
我的 reducer :

const newsReducer = (state = initialState, action) => {
  switch (action.type) {
    case actionTypes.ADD_COMMENT:
      const { id, author, commentText, newsItemId } = action.payload;
      // which element to update
      const index = state.news.findIndex(item => item.id === newsItemId);
      return {
        ...state,
        news: [
          ...state.news
          [index] = {
            ...state.news[index],
            comments: state.news[index].comments.concat({ id, author, commentText })
          }
        ]
      }
    default:
      return state;
  }
}

如有任何建议,我们将不胜感激

最佳答案

扩展语法是解决此问题的一种方法,另一种方法是使用镜头,可以在 Ramda 等库中找到它。 .

镜头可让您“缩放”数据结构的特定部分并更新值,从而返回整个数据结构的新版本。

const R = require('ramda')
const a = {a:'foo', b:[1, 2, 3]}
const b = R.over(R.lensPath(['b']), nums => nums.concat(4), a)
console.log(b) //-> {a:'foo', b:[1, 2, 3, 4]}

使用透镜,您的 reducer 可以表示为:

const R = require('ramda')
const newsReducer = (state = initialState, action) => {
  switch (action.type) {
    case actionTypes.ADD_COMMENT:
      const { id, author, commentText, newsItemId } = action.payload
      const i = state.news.findIndex(item => item.id === newsItemId)
      return R.over(
        R.lensPath(['news', i, 'comments']),
        comments => comments.concat({ id, author, commentText }),
        state
      )
      default:
        return state;
  }
}

关于javascript - 如何以不可变的方式更新数组,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52196291/

相关文章:

node.js - mongodb : fetch API POST request returns a strange response

javascript - 使用过滤器在 Angularjs 中执行搜索后清除列表?

javascript - 在 Canvas 元素上旋转 Sprite

android - 确定 JSON 是 JSONObject 还是 JSONArray

javascript - 防止特定属性在react js中的DOM节点上渲染

reactjs - 如何在 Victory Pie 中的数据对象中指定色阶

javascript - 使用 JS 按日期/时间对 div 进行排序

javascript - jQuery - 为什么委托(delegate)传播,即使在调用 `e.preventDefault` 之后?

javascript - 反转字符串首字母大写?JavaScript

javascript - 根据字符串中的字符对字符串数组进行排序