Как правильно передать массив в хук 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) (второй аутпут). Как можем заметить, они одинаковы.
Суть вопроса
- Как вышло, что принимая одинаковые значения программа выдает разный результат?
- Каким образом нужно передавать значение состояния, чтобы оно рендерилось корректно?
Извините за столь глупые вопросы, просто большинство документации о состояниях касается классовых компонентов, которые в данном случае мне не интересны. Заранее спасибо за ваши ответы :3
P.S: Ссылка на песочницу с кодом [https://codepen.io/ilias_zet/pen/abBomGY?editors=0010][3] . Кстати, проверка показала, что `newPosts != newPosts.concat([])`
`
Ответы (2 шт):
Ссылка на песочницу с кодом в codepen https://codepen.io/ilias_zet/pen/abBomGY?editors=0010
(newPosts.concat([])==newPosts) //false
Вот рабочий код твоего примера. Я думаю если почитать код будет всё понятно, если есть вопросы задавай в коментах.
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;

