#javascript #html #node.js #reactjs #conditional-statements
Вопрос:
Я пытаюсь создать строку и кнопку «Не нравится» в React.js. У меня есть два тега, которые содержат значки Google, и при нажатии на значки они должны изменяться в режиме реального времени без необходимости обновлять страницу.
Но они не меняются без обновления страницы. Я использую MacBook Air и использую как браузер Safari, так и браузер Brave, но он не работает.
Кодировка моей страницы выглядит следующим образом :-
import React, { useState, useEffect, useContext } from 'react';
import {UserContext} from '../../App';
const Home = () => {
const [data, setData] = useState([]);
const { state, dispatch } = useContext(UserContext); // eslint-disable-line
useEffect(() => {
fetch('/allpost', {
headers: {
"Authorization": "Bearer " localStorage.getItem("jwt")
}
}).then(res => res.json()).then(result => {
setData(result.posts);
});
}, []);
const likePost = (id) => {
fetch('/like', {
method: "put",
headers: {
"Content-Type": "application/json",
"Authorization": "Bearer " localStorage.getItem("jwt")
},
body: JSON.stringify({
postId: id
})
}).then(res => res.json()).then(result => {
const newData = data.map(item => {
if (item._id == result._id) { // eslint-disable-line
return resu<
} else {
return item;
}
})
setData(newData);
}).catch(err => {
console.log(err);
});
}
const dislikePost = (id) => {
fetch('/dislike', {
method: "put",
headers: {
"Content-Type": "application/json",
"Authorization": "Bearer " localStorage.getItem("jwt")
},
body: JSON.stringify({
postId: id
})
}).then(res => res.json()).then(result => {
const newData = data.map(item => {
if (item._id == result._id) { // eslint-disable-line
return resu<
} else {
return item;
}
})
setData(newData);
}).catch(err => {
console.log(err);
});
}
return (
<div className="home">
{
data.map(item => {
return (
<div className="card home-card" style={{ borderRadius:"6px" }} key={item._id}>
<h6 style={{ paddingLeft: "10px", paddingTop:"10px", fontSize:"17px" }}>{ item.postedBy.name }</h6>
<div className="card-image">
<img src={ item.photo } style={{ paddingLeft:"6px", paddingRight:"6px" }} alt="Posted photograph" />
</div>
<div className="card-content">
{item.likes.includes(state._id)
?
<i className="material-icons" style={{ color: "red" }} onClick={() => { dislikePost(item._id) }}>favorite_border</i>
:
<i className="material-icons" style={{ color: "red" }} onClick={() => {likePost(item._id)}}>favorite</i>
}
<h6>{item.likes.length} likes</h6>
<h6>{ item.title }</h6>
<p>{ item.body }</p>
<input type="text" placeholder="Add a comment here." />
</div>
</div>
);
})
}
</div>
);
}
export default Home;
Я специально упоминаю, где написана моя логика изменения значка. Это выглядит следующим образом :
<div className="card-content">
{item.likes.includes(state._id)
?
<i className="material-icons" style={{ color: "red" }} onClick={() => { dislikePost(item._id) }}>favorite_border</i>
:
<i className="material-icons" style={{ color: "red" }} onClick={() => {likePost(item._id)}}>favorite</i>
}
<h6>{item.likes.length} likes</h6>
<h6>{ item.title }</h6>
<p>{ item.body }</p>
<input type="text" placeholder="Add a comment here." />
</div>
Комментарии:
1. Итак, проблема в том, что ваша логика обновляет только локальное
data
состояние, а неstate
предоставляется из контекста? Что конкретноstate
означает иstate._id
представляет собой?2. Как отметил @DrewReese . Проблема здесь
item.likes.includes(state._id)
. так что при onClick, помимо запуска состояния, вам также необходимо обновить контекст .
Ответ №1:
Это не имеет отношения к данному вопросу . Но если вы готовы к рефакторингу, то я бы посоветовал вам изменить функции «Нравится» и «Не нравится» в одну функцию . Потому что обе функции выполняют одно и то же, за исключением того, что у них другой URL-адрес, который вы можете передать в качестве аргумента функции.
const updatePostLikes = (id, url) => {
fetch(url, {
method: 'put',
headers: {
'Content-Type': 'application/json',
Authorization: 'Bearer ' localStorage.getItem('jwt'),
},
body: JSON.stringify({
postId: id,
}),
})
.then((res) => res.json())
.then((result) => {
const newData = data.map((item) => {
if (item._id == result._id) {
// eslint-disable-line
return resu<
} else {
return item;
}
});
setData(newData);
})
.catch((err) => {
console.log(err);
});
}
И когда вы нажмете на кнопку «Нравится» и «не нравится», теперь вы можете сделать это
updatePostLikes(item._id, '/like') // for likes
updatePostLikes(item._id, '/dislike') // for dislikes