Ссылка на массив ведет себя как копия - PullRequest
1 голос
/ 28 апреля 2019

У меня есть простое приложение React с таблицей сообщений: enter image description here

В начале приложение всегда имеет 100 сообщений.

Вот как яобрабатывать операцию УДАЛИТЬ:

  handleDelete = async post => {
    const oldPosts = this.state.posts;

    const posts = this.state.posts.filter(n => n.id !== post.id);
    this.setState({ posts });

    try {
      await axios.delete(`${apiEndpoint}/${post.id}`);
      console.log(oldPosts);
    } catch (e) {
      alert("There was an error while removing post " + post.id);
    }
  };

Переменная oldPosts содержит массив ССЫЛКИ на сообщения.Как вы можете видеть в следующих двух строках, я обновляю состояние меньшим количеством постов (99 из них).Я ожидаю, что моя ссылка oldPosts будет указывать на этот массив из 99 элементов.Однако, когда это console.logged, я вижу 100 элементов.Почему это?

Ответы [ 4 ]

3 голосов
/ 28 апреля 2019
  const oldPosts = this.state.posts;

То, что копирует ссылку на массив в переменную oldPost. Если массив внутри this.state.posts будет изменен, вы увидите эти изменения внутри oldPosts, но если сама ссылка будет изменена, то oldPost и this.state.posts указывают на два разных массива.

Используя .filter, вы создаете новый массив.

1 голос
/ 28 апреля 2019

Я ожидаю, что моя ссылка oldPosts будет указывать на этот элемент с 99 элементами. массив. Однако, когда это console.logged, я вижу 100 элементов. Почему что?

Хороший вопрос, позвольте мне попытаться объяснить. В этом случае массив будет храниться в некоторой ячейке памяти, а this.state.posts будет иметь ссылку на этот array. Вы ссылаетесь на тот же array с помощью oldPosts, это означает, что oldPosts указывает на массив, а не на this.state.posts.

Когда мы обновим значение this.state.posts, у него будет новый ref, ref для вновь созданного array, а не для старого массива. Но этот oldPosts все еще будет указывать на старый массив.

Даже если вы назначите любое значение, кроме массива, оно никогда не повлияет на значение oldPosts.

Посмотрите на этот пример, вы получите лучшее представление:

// consider this as state obj
let obj = {
  posts: [1, 2, 3, 4],
}

let oldPosts = obj.posts;
let newPosts = obj.posts.filter(el => el < 4);

// same as setState
obj.posts = newPosts;

// still point to old array
console.log('oldPosts', oldPosts);

// it will have the new array
console.log('obj.posts', obj.posts);

obj.posts = 10;

// now it will have a totally new value
console.log('obj.posts', obj.posts);

Проверьте еще один пример:

let a = [1, 2, 3, 4];
let b = a;

/* 
  a and b both points to same array, but if we assign a 
   new value to a, b will still points to array
*/

a = 10;

// by changing the value of a, it will not affect b
console.log('a', a);

// still point to array
console.log('b', b);
0 голосов
/ 28 апреля 2019

Вы не обновляете свое состояние oldPosts.это должно работать

  this.setState({ oldPosts : posts }); 

Спасибо

0 голосов
/ 28 апреля 2019

Вы назначаете 100 posts на oldPosts.Затем вы фильтруете posts для получения нового массива и сохранения в состоянии.Фильтр возвращает новый массив и не обновляет фактический массив, т.е. oldPosts.Если вы хотите это поведение, вы можете использовать Array.prototype.splice

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/splice

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...