Как правильно передать массив в хук useState() React.js

Только на днях начал изучать React.js, так что не судите строго :)

Я использую функциональный подход к описанию компонентов. Суть приложения проста: имеется кнопка "Likes" на компоненте <Post/ >. На кнопке должно быть написано количество лайков. При нажатии на кнопку значение увеличивается на единицу. Я реализовал это следующим образом:

var newPosts=[]
function Content(){
  const [posts,setPosts] = React.useState([
  {title:'title1',
  text:'text1',
  id:1,
  likes:0,},
  ])
  newPosts = posts
  const likeFunc = (id) =>{
    
    newPosts.map((post) =>{if(post.id===id){
      post.likes++
    }})
    console.log(newPosts)
    setPosts(newPosts)
  }

Массив posts хранит в себе объекты с информацией о каждом существующем посте. Метод setPosts() должен изменять состояние компонента <Content /> и передавать в него массив с текущими обновленными значениями объектов. И действительно, вывод в консоль показывает, что свойства объекта изменены. Но значение переменной на кнопке не обновляется

Вывод консоли после первого нажатия

Немного мистики. Если в setPosts() передавать тот же самый массив newPosts, но применить к нему метод concat([]), который по-факту его никак не изменяет, все сразу начинает работать правильно и на кнопке отображается нужное значение

Следующее изображение иллюстрирует результат работы такого подхода

введите сюда описание изображения

Значения в консоли выводятся из console.log(newPosts.concat([])) (первый аутпут) и console.log(newPosts) (второй аутпут). Как можем заметить, они одинаковы.

Суть вопроса

  1. Как вышло, что принимая одинаковые значения программа выдает разный результат?
  2. Каким образом нужно передавать значение состояния, чтобы оно рендерилось корректно?

Извините за столь глупые вопросы, просто большинство документации о состояниях касается классовых компонентов, которые в данном случае мне не интересны. Заранее спасибо за ваши ответы :3

P.S: Ссылка на песочницу с кодом [https://codepen.io/ilias_zet/pen/abBomGY?editors=0010][3] . Кстати, проверка показала, что `newPosts != newPosts.concat([])`

`


Ответы (2 шт):

Автор решения: Ilias

Ссылка на песочницу с кодом в codepen https://codepen.io/ilias_zet/pen/abBomGY?editors=0010

(newPosts.concat([])==newPosts) //false

→ Ссылка
Автор решения: Konstantin Modin

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

import React, { useState } from "react";

const App = () => {
  const initialState = [
    { id: 1, title: "Title1", text: "Text1", likes: 0 },
    { id: 2, title: "Title2", text: "Text2", likes: 1 },
    { id: 3, title: "Title3", text: "Text3", likes: 2 },
  ];

  const [posts, setPosts] = useState(initialState);

  const likeHandler = (id) => {
    setPosts(
      posts.map((item) =>
        item.id === id ? { ...item, likes: item.likes + 1 } : item
      )
    );
  };

  const deleteHandler = (id) => {
    setPosts(posts.filter((item) => item.id !== id));
  };

  return (
    <div>
      Posts:
      {posts.map(({ id, title, text, likes }) => (
        <div key={id}>
          <h1>{title}</h1>
          <h3>{text}</h3>
          <button onClick={() => likeHandler(id)}>Likes: {likes}</button>
          <button onClick={() => deleteHandler(id)}>Delete</button>
        </div>
      ))}
    </div>
  );
};

export default App;
→ Ссылка