Я новичок в реакции, я знаю, что это вопрос, но я не знаю, как его решить.
Мне нужно сделать более одной кнопки-сердца и изменить опору paramether, которую я пометил isChecked, на true или false, чтобы кнопка изменилась с HeartNormal на HeartFull.
В коде не может быть состояния для этого, потому что каждая кнопка должна переключаться между HeartNormal и HeartFull отдельно.
import React, { Component } from 'react';
class Test extends Component {
handleLike = props =>{
props.isCheck = true;
}
renderer(){
return(
<div>
<Heart isClicked = {false} onClick = {() => this.handleLike(this.props)}/>
<Heart isClicked = {false} onClick = {() => this.handleLike(this.props)}/>
<Heart isClicked = {false} onClick = {() => this.handleLike(this.props)}/>
<Heart isClicked = {false} onClick = {() => this.handleLike(this.props)}/>
<Heart isClicked = {false} onClick = {() => this.handleLike(this.props)}/>
</div>
)
}
}
function Heart(props){
const isClicked = props.isClicked;
if (isClicked){
return <button onClick = {props.onClick}><i className = "fas fa-heart"></i></button>
}else{
return <button onClick = {props.onClick}><i className = "far fa-heart"></i></button>
}
}
export default Test;
В handleLike есть другие параметры, чтобы пригласить идентификатор понравившегося сообщения на сервер узла, потому что это идеальная структура для создания кода для меня. Я надеюсь, что кто-нибудь может помочь мне исправить это.
Каждую кнопку нужно менять отдельно. Этот код был предназначен только для проверки изменений между Нормальным Сердцем и Полным Сердцем. В основном код получает идентификатор из сообщения и отправляет URL-адрес, подобный этому «localhost: 3000/posts/5d194d2db9ec4dbb68b13145/like», используя метод POST, сервер узла получает идентификатор из URL-адреса и добавляет лайк.



![Безумие обратных вызовов в javascript [JS]](https://i.imgur.com/WsjO6zJb.png)


Проблема: Вы не можете назначать свойства в React, потому что они доступны только для чтения. Способ обновления реквизита — обновить значение, которое родитель отправляет этому компоненту.
Значение <Test isCheck = {/* change the value here */} />
Решение: вы можете использовать состояние для каждого отдельного компонента Heart с помощью Реагировать на хуки. Таким образом, каждый Heart будет иметь отдельное состояние, независимое друг от друга, и компоненту Test не нужно будет отслеживать каждое состояние.
Вот обновленный код:
import React, { Component } from 'react';
class Test extends Component {
renderer(){
return(
<div>
<Heart/>
<Heart/>
<Heart/>
<Heart/>
<Heart/>
</div>
)
}
}
function Heart(props){
const [isClicked, setIsClicked] = useState(false);
return (
<button onClick = {() -> setIsClicked(true)}>
<i className = {clicked ? "fas fa-heart" : "far fa-heart"}></i>
</button>
);
}
export default Test;
Вам нужно сделать Heart компонентом с состоянием, тогда каждое ваше сердце будет иметь состояния отдельно и отображаться по-разному.
import React, { Component } from 'react';
class Test extends Component {
//should be render
render(){
return(
<div>
<Heart isClicked = {false} />
<Heart isClicked = {false} />
<Heart isClicked = {false} />
</div>
)
}
}
class Heart extends Component {
constructor(props){
super(props)
this.state = {
clicked: this.props.isClicked
}
}
handleClick = () => {
this.setState({clicked: !this.state.clicked})
}
render(){
const {clicked} = this.state
return(<button onClick = {() => this.handleClick()}>
<i className = {clicked ? "fas fa-heart" : "far fa-heart"}></i>
</button>)
}
}
export default Test;
Здесь нужно использовать состояние. Что вы можете сделать, так это сохранить массив в вашем Test компоненте state, который представляет каждое сердце, а затем изменить их по отдельности.
Это будет выглядеть примерно так:
class Test extends Component {
constructor(props) {
super(props);
this.state = {
hearts: [
{ liked: false },
{ liked: false },
{ liked: false },
{ liked: false },
{ liked: false }
]
};
}
handleHeartClick(heartIndex) {
let clickedHeart;
this.setState({
hearts: this.state.hearts.map((heart, index) => {
if (index === heartIndex) {
heart.isCheck = !heart.isCheck;
clickedHeart = heart;
}
return heart;
});
});
// Send your clickedHeart off to your node server, or whatever else you need with it
}
render() {
const heartComponents = this.state.hearts.map((heart, index) => (
<Heart isClicked = {heart.isCheck} onClick = {() => this.handleHeartClick(index)} />
));
return (
<div>
{heartComponents}
</div>
);
}
}
Другие ответы хороши, особенно использование Брэндоном Хуки, однако этот сохраняет логику ваших данных в контейнере и упрощает ваш презентационный компонент.
Другие ответы верны, если сердцам не нужно ничего знать друг о друге, но я не думаю, что это ваш случай. Если я нажму на третье сердце, вы, вероятно, также захотите, чтобы #1 и #2 заполнились. В этом случае ваше состояние должно быть взято вне компонента Heart и перемещено вверх к компоненту Test:
import React, { useState } from "react"
const Test = () => {
// How many hearts do you want to show?
const numberOfHearts = 5
// Start with no hearts filled in
const [likeValue, setLikeValue] = useState(0)
const handleClick = (heartValue) => {
setLikeValue(heartValue)
// Update your database with the new value of likes
}
// Loop to show as many hearts as you set above
const hearts = [...Array(numberOfHearts).keys()].map((v) => {
// v is 0 for the first, 1 for the second, etc
return (
<Heart
isLiked = {likeValue > v}
key = {v}
heartValue = {v + 1}
handleClick = {handleClick}
/>
)
})
return <div>{hearts}</div>
}
const Heart = ({ handleClick, heartValue, isLiked }) => {
return (
<button onClick = {() => handleClick(heartValue)}>
<i className = {isLiked ? "fas fa-heart" : "far fa-heart"} />
</button>
)
}
Когда вы нажмете на третье сердце, № 1, № 2 и № 3 будут «лайкать», а № 4 и № 5 - нет. Таким образом, другие решения работают, если вы хотите щелкнуть № 3 и заполнить только третье сердце, но если это больше похоже на рейтинговую систему, вы должны поднять состояние и управлять им на уровне родительского (тестового) компонента.
Нужно ли тесту знать что-либо о состоянии компонента «Сердце»? Например, что произойдет, если я нажму на третье сердце — должны ли сердца 1 и 2 также переключаться? И если да, то какой из них должен отправлять информацию на сервер вашего узла?