Состояния Redux странно меняются - PullRequest
0 голосов
/ 23 января 2019

У меня есть 2 разных состояния, и одно состояние содержит часть второго.Дело в том, что при изменении второго состояния изменяется и то, что находится в первом состоянии, и я не могу понять, почему.

Вот когда я изменяю второе состояние:

    case 'UPDATE_IMAGES':
        return Object.assign({}, state, {
            runes: updateChosenState(state, action)
        });

export function updateChosenState(state,action){
    const img = state.images.slice();
    let e = action.e;
    imga[].id_ = action.id;
    return img;
}

Первое состояние обращается таким образом в действии, которое затем передается редуктору:

let img = getState().ImgReducer.images;

В редукторе у меня есть некоторая функция, которую необходимо выполнить, когда она связана:

                const copy = images.slice();
                items.image = copy[idGiven];

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

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

Спасибо вам

1 Ответ

0 голосов
/ 23 января 2019

Когда вы используете slice для массива, возвращаемый массив не является настоящим клоном.Вместо этого вы получили мелкую копию массива.Следовательно, и копия, и исходные объекты внутри массива указывают на одну и ту же ссылку на память.

Из документов Array#slice в MDN:

Чтобы ссылаться на объект, slice скопируйте ссылку внутри нового массива.И оригинальный, и новый массив указывают на один и тот же объект.Если ссылочный объект изменяется, изменения видны для обоих массивов.

Это можно проверить с помощью следующего примера:

const original = { src: 'foo' }
const images = [original]
const copy = images.slice()

original.src = 'baz'
console.log(copy)

Решение

Вам необходимо сделать глубокий клон элемента.Вы можете сделать это с помощью оператора распространения:

const original = { src: 'foo' }
const images = [original]
const copy = images.slice().map(o => ({ ...o }))

original.src = 'baz'
console.log(copy)

Еще один способ достижения той же цели - использование JSON#stringify и JSON#parse:

const original = { src: 'foo' }
const images = [original]
const copy = JSON.parse(JSON.stringify(original))

original.src = 'baz'
console.log(copy)
...