Javascript.RU

Создать новую тему Ответ
 
Опции темы Искать в теме
  #1 (permalink)  
Старый 16.11.2018, 10:32
Интересующийся
Отправить личное сообщение для dmitry.suhotsky Посмотреть профиль Найти все сообщения от dmitry.suhotsky
 
Регистрация: 16.11.2018
Сообщений: 10

Изменить значение в state массива

По нажанию на лайк, должен измениться цвет и увеличится кол-во на +1. Повторное нажание -1.

Компанент для вывода итемов
import React, { Component } from 'react';
export default class Items extends Component {
handleClick = () => {
  };

render() {
    return(
    <div className="items">
    {this.props.mass.map((i, index) => {
        return (
        <div className="item" key={index}>
            <div className="item__img">
                 <img src={i.img} alt="rose" /> 
            </div>
            <div className="item__text">
                <p className="item__title">{i.title}</p>
                <p className="item__hashtag">{i.hashtag}</p>
                <i className="fa fa-eye"></i><span className="item__viev">{i.viev}</span>
                <i className="fa fa-heart" onClick={this.handleClick({index})}></i><span className="item__like">{i.like}</span>
            </div>
        </div>
        )
    })}
    </div>
    );
}
}

Еще компонент, из которого я передаю значения
import React, { Component } from 'react';
import Background from '../img/cyprus-3184019_1920.jpg';
import Items from './Items';
import RoseImg from '../img/rose.jpg';
import LeafImg from '../img/leaf.jpg';

export default class Main extends Component {
    constructor(props){
        super();
        this.state = {
            mass : [{
                id: 1,
                img: RoseImg,
                title: '1Beautiful mint and glass bowl',
                hashtag: '#beauty #glass #mint #green #white #health',
                viev: 1130,
                like: 30,
                click: false
            },
            {
                id: 2,
                img: LeafImg,
                title: '2Beautiful mint and glass bowl',
                hashtag: '#beauty #glass #mint #green #white #health',
                viev: 1130,
                like: 20,
                click: false
            },
            {
                id: 3,
                img: RoseImg,
                title: '3Beautiful mint and glass bowl',
                hashtag: '#beauty #glass #mint #green #white #health',
                viev: 1130,
                like: 35,
                click: false
            }]
        }
    }
  render() {
    var sectionStyle = {
        width: "100%",
        height: "100%",
        backgroundImage: `url(${Background})`
      };
    return (
      <div className="main" style={ sectionStyle }>
        <div className="container">
            <h1>World’s most <span className="main__span">amazing</span> test tiles</h1>
            <Items mass={this.state.mass}/>
        </div>
      </div>
    );
  }
}

Как я думаю. По клику onClick={this.handleClick} вызывается функция, в которой ({{index}}) передается текущий итем.

1)берется текущий стейт
2) вытягиваем лайк
3) увеличиваем на 1
4) обновляем
handleClick = (i) => {
    const newMass = this.state.mass[i];
    newMass.like =  this.state.mass[i].like +1 ;
    this.setState({
        mass: newMass
    })
  };

Помогите разобраться

Последний раз редактировалось dmitry.suhotsky, 16.11.2018 в 10:53.
Ответить с цитированием
  #2 (permalink)  
Старый 16.11.2018, 10:33
Профессор
Отправить личное сообщение для Nexus Посмотреть профиль Найти все сообщения от Nexus
 
Регистрация: 04.12.2012
Сообщений: 3,795

Пожалуйста, отформатируйте свой код!

Для этого его можно заключить в специальные теги: js/css/html и т.п., например:
[js]
... ваш код...
[/js]


О том, как вставить в сообщение исполняемый javascript и html-код, а также о дополнительных возможностях форматирования - читайте http://javascript.ru/formatting.
Ответить с цитированием
  #3 (permalink)  
Старый 16.11.2018, 10:41
Профессор
Отправить личное сообщение для Nexus Посмотреть профиль Найти все сообщения от Nexus
 
Регистрация: 04.12.2012
Сообщений: 3,795

Сообщение от dmitry.suhotsky
Как я думаю. По клику onClick={this.handleClick} вызывается функция, в которой ({{index}}) передается текущий итем.
Передается не item, а его index.

Сообщение от dmitry.suhotsky
handleClick = (i) => {
const newMass = this.state.mass[i];
newMass.like = this.state.mass[i].like +1 ;
this.setState({
mass: newMass
})
У вас в state.mass должен находится массив объектов, а вы после обработки клика записываете в него объект, по которому кликнули.
Попробуйте так:
handleClick = index => {
    const list = this.state.mass;
    const item = list[index];

    item.like += item.click ? -1 : 1;
    item.click = !item.click;

    list[index] = item;

    this.setState({
        mass: list
    });
}
Ответить с цитированием
  #4 (permalink)  
Старый 16.11.2018, 11:06
Аватар для SuperZen
Профессор
Отправить личное сообщение для SuperZen Посмотреть профиль Найти все сообщения от SuperZen
 
Регистрация: 08.11.2017
Сообщений: 641

Nexus, в таком варианте handleClick изменения будут в самом this.state.mass, но поскольку вся фича реакта, не изменять текущий стейт напрямую, и, соответственно, это неправильно. Надо сначала сделать клон объекта, и в нем уже менять... а то не будут time travel )))
Ответить с цитированием
  #5 (permalink)  
Старый 16.11.2018, 11:21
Профессор
Отправить личное сообщение для Nexus Посмотреть профиль Найти все сообщения от Nexus
 
Регистрация: 04.12.2012
Сообщений: 3,795

SuperZen, вам виднее, я с реактом на Вы)
Правильно ли будет перенести данные из state в props?
Ответить с цитированием
  #6 (permalink)  
Старый 16.11.2018, 11:42
Интересующийся
Отправить личное сообщение для dmitry.suhotsky Посмотреть профиль Найти все сообщения от dmitry.suhotsky
 
Регистрация: 16.11.2018
Сообщений: 10

Подскажите тогда
при нажатии onClick={this.handleClick}
вызываю лог
export default class Items extends Component {
    handleClick = index => {
        console.log('Click');
    }

Все отрабатывает. Как по нажатию в лог вывести текущий like?

делаю так и вылетает ошибка
handleClick = index => {
         const list = this.props.mass; //клон mass array
         const item = list[index]; // mass[item] кликнутый итем
         item.like = 1; //меняем текушее значение на 1
         list[index] = item; //обновляем клон
         this.setState({
             mass: list  //обновляем state
         });
        console.log('Clock');
    }

Ошибка TypeError: Cannot set property 'like' of undefined
Ответить с цитированием
  #7 (permalink)  
Старый 16.11.2018, 11:59
Профессор
Отправить личное сообщение для Nexus Посмотреть профиль Найти все сообщения от Nexus
 
Регистрация: 04.12.2012
Сообщений: 3,795

dmitry.suhotsky, попробуйте классу Items добавить такой конструктор:
constructor(props){
    super(props);

    this.handleClick=this.handleClick.bind(this);
}
Ответить с цитированием
  #8 (permalink)  
Старый 16.11.2018, 12:04
Аватар для SuperZen
Профессор
Отправить личное сообщение для SuperZen Посмотреть профиль Найти все сообщения от SuperZen
 
Регистрация: 08.11.2017
Сообщений: 641

Nexus, из props в state если только для формы, которая требует валидации... лучше конечно разобраться с context, чтобы горадули не годарить )

dmitry.suhotsky, в первом посте

onClick={this.handleClick({index})}

заменить на
onClick={() => this.handleClick({i, index})}


только тогда, при каждом ререндерере будет пересоздаваться ф-ция, при больших объемах (сотни-тыщи) это будут влиять на производительность, а если штук 10-50, то можно забить... или если прям хочется идеалов, тогда надо осознать это https://reactjs.org/docs/optimizing-performance.html
Ответить с цитированием
  #9 (permalink)  
Старый 16.11.2018, 12:09
Профессор
Отправить личное сообщение для Nexus Посмотреть профиль Найти все сообщения от Nexus
 
Регистрация: 04.12.2012
Сообщений: 3,795

SuperZen,
Сообщение от SuperZen
из props в state
я про "наоборот" спрашивал, из state в props.
Ответить с цитированием
  #10 (permalink)  
Старый 16.11.2018, 12:15
Аватар для SuperZen
Профессор
Отправить личное сообщение для SuperZen Посмотреть профиль Найти все сообщения от SuperZen
 
Регистрация: 08.11.2017
Сообщений: 641

Nexus, ну тогда через пропсы должна быть передана ф-ция из родительского компонента, которая будет вызвана с дочерним стейт... в общем надо смотреть context, или redux, или mobx, или ) apolloGraphQL...
Ответить с цитированием
Ответ



Опции темы Искать в теме
Искать в теме:

Расширенный поиск


Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Найти максимальное и минимальное значение в элементах DOM smart-create Events/DOM/Window 17 11.07.2017 13:36
не могу программно изменить значение textarea в онлайн редакторе rusik Общие вопросы Javascript 6 24.10.2015 15:01
Присвоить значение hidden и -200% когда div закрыт xrror Элементы интерфейса 0 20.09.2013 16:47
Выводить значение раньше переменных Гробовщик Общие вопросы Javascript 11 10.09.2013 08:42
Скажите, а возможно ли вычислить максимальное значение массива? Solovei95 Общие вопросы Javascript 5 28.01.2012 13:46