Обновление и изменение положения объекта в массиве редуктора Redux.

1
const state = [
  {10: {a: 22, b: 33}},
  {12: {a: 20, b: 33}},
  {15: {a: 22, b: 34}},
  {5: {a: 21, b: 30}},
  {9: {a: 29, b: 33}},
]

State - это массив объектов, как указано выше. Когда приложение обновляет объект, объект должен перетекать в первую позицию.

Например, предположим, что мы берем второй объект выше (с основным ключом 12) и копируем и обновляем его так, чтобы он выглядел следующим образом:

{12: {a: 45, b: 33}}

И теперь мы хотим вставить его в массив со следующим результатом:

const state = [
  {12: {a: 45, b: 33}},
  {10: {a: 22, b: 33}},
  {15: {a: 22, b: 34}},
  {5: {a: 21, b: 30}},
  {9: {a: 29, b: 33}},
]

Я понимаю, как обновлять объект неизменно, но я не могу понять, как это сделать.

  • 1
    Обновленный ответ ниже. Если это не поможет, можете ли вы уточнить, какая часть процесса ставит вас в тупик?
Теги:
redux

2 ответа

1
Лучший ответ

Вы можете использовать что-то вроде

// an update function, here it just adds a new key
// to the object
const update = (x) => ({
  ...x,
  hello: "world"
});

// a filter factory
const withId = (id) => (item) => Boolean(item[id]); // item with specific ids
const withoutId = (id) => (item) => !Boolean(item[id]); // others

const state = [
  {10: {a: 22, b: 33}},
  {12: {a: 20, b: 33}},
  {15: {a: 22, b: 34}},
  {5: {a: 21, b: 30}},
  {9: {a: 29, b: 33}},
];

const id = 5;
const newState = state
  .filter(withId(id))
  .map(update)
  .concat(state.filter(withoutId(id)));


console.log(JSON.stringify(newState, null, 4));

Это означает, что фильтрация состояния между элементами, которые вы хотите обновить, и остальными, применить обновление к выбору и согласовать нетронутые элементы для них.

Ниже приведен другой пример с той же идеей, которая иллюстрирует, что вы можете выполнить обновление более чем для одного элемента:

const markAsDone = (todo) => ({
  ...todo,
  done: true
});
const isInGroup = (group) => (todo) => todo.group === group;
const not = (predicate) => (x) => !predicate(x);

const isWork = isInGroup("work");
const notWork = not(isWork);

const state = [
  {
    todo: "go shopping",
    group: "life"
  },
  {
    todo: "go work",
    group: "work",
  },
  {
    todo: "go sleep",
    group: "life"
  }
];

// get work related todos, mark as done and 
// append to todo list
const newState = state
  .filter(notWork)
  .concat(state
    .filter(isWork)
    .map(markAsDone));


console.log(JSON.stringify(newState, null, 4));
  • 0
    Будучи новичком, это изменяет состояние неизменным образом?
  • 1
    iep, функция update создает совершенно новый объект, который объединяет старый и добавляет новое свойство, оставляя старое без изменений, map filter и concat также создают новые массивы. Логика в этом скрипте состоит в том, чтобы отфильтровать нужные элементы, обновить их неизменным образом и сопоставить результаты с остальными.
Показать ещё 2 комментария
1

что-то вроде этого возможно?

const state = [
  {10: {a: 22, b: 33}},
  {12: {a: 20, b: 33}},
  {15: {a: 22, b: 34}},
  {5: {a: 21, b: 30}},
  {9: {a: 29, b: 33}},
]


// find the numerical index of the object with the specified "key"
function findIndexOfKey(array, key){
  return array.findIndex(function(el){return key in el});
}


// modify object and move to front
function editObjectAndMoveToFront(array, key, updatedValues){
  // find index of object with key, for use in splicing
  var index = findIndexOfKey(array, key);

  // create the updated version of the specified object
  var originalObject = array[index];
  var originalObjectValue = originalObject[key];
  var editedObject = {};
  editedObject[key] =  Object.assign({}, originalObjectValue, updatedValues)

  // here is the new state, with the updated object at the front
  var newArray = [
    editedObject,
    ...array.slice(0, index),
    ...array.slice(index + 1)
  ]
  return newArray
}


const newState = editObjectAndMoveToFront(state, 12, {a: 45, b: 33})
console.log(newState);

Ещё вопросы

Сообщество Overcoder
Наверх
Меню