Как установить реквизит из функции

Я новичок в реакции, я знаю, что это вопрос, но я не знаю, как его решить.

Мне нужно сделать более одной кнопки-сердца и изменить опору 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 есть другие параметры, чтобы пригласить идентификатор понравившегося сообщения на сервер узла, потому что это идеальная структура для создания кода для меня. Я надеюсь, что кто-нибудь может помочь мне исправить это.

Нужно ли тесту знать что-либо о состоянии компонента «Сердце»? Например, что произойдет, если я нажму на третье сердце — должны ли сердца 1 и 2 также переключаться? И если да, то какой из них должен отправлять информацию на сервер вашего узла?

I'm Joe Too 11.07.2019 22:54

Каждую кнопку нужно менять отдельно. Этот код был предназначен только для проверки изменений между Нормальным Сердцем и Полным Сердцем. В основном код получает идентификатор из сообщения и отправляет URL-адрес, подобный этому «localhost: 3000/posts/5d194d2db9ec4dbb68b13145/like», используя метод POST, сервер узла получает идентификатор из URL-адреса и добавляет лайк.

Nícolas Thiesen 11.07.2019 23:14
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
В настоящее время производительность загрузки веб-сайта имеет решающее значение не только для удобства пользователей, но и для ранжирования в...
Безумие обратных вызовов в javascript [JS]
Безумие обратных вызовов в javascript [JS]
Здравствуйте! Юный падаван 🚀. Присоединяйся ко мне, чтобы разобраться в одной из самых запутанных концепций, когда вы начинаете изучать мир...
Система управления парковками с использованием HTML, CSS и JavaScript
Система управления парковками с использованием HTML, CSS и JavaScript
Веб-сайт по управлению парковками был создан с использованием HTML, CSS и JavaScript. Это простой сайт, ничего вычурного. Основная цель -...
JavaScript Вопросы с множественным выбором и ответы
JavaScript Вопросы с множественным выбором и ответы
Если вы ищете платформу, которая предоставляет вам бесплатный тест JavaScript MCQ (Multiple Choice Questions With Answers) для оценки ваших знаний,...
4
2
922
4
Перейти к ответу Данный вопрос помечен как решенный

Ответы 4

Проблема: Вы не можете назначать свойства в 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 и заполнить только третье сердце, но если это больше похоже на рейтинговую систему, вы должны поднять состояние и управлять им на уровне родительского (тестового) компонента.

Другие вопросы по теме