• React: Как перебросит данные из объекта на другой компонент?

    @Dartess
    Если у вас одни и те же данные шарятся между разными страницами, эти данные вполне сойдут за глобальное состояние приложения.

    Есть несколько способов его хранить и менять:

    а) хранить данные в контексте и получать их и метод для их изменения путём подключения к контексту (см. useContext или contextType, в зависимости от функциональности/классовости компонента).
    б) использовать сторонние решения для управления состоянием. На выбор redux, mobx, effector и прочие библиотеки.
    Ответ написан
    2 комментария
  • Как реализовать лайк на чистом js?

    0xD34F
    @0xD34F Куратор тега JavaScript
    Делегирование, назначаем обработчик клика один раз:

    // при клике по кнопке определяем её индекс и хватаем .photos__like-count с таким же индексом
    document.addEventListener('click', ({ target: t }) => {
      if (t.classList.contains('photos__like-icon')) {
        const index = [...document.querySelectorAll('.photos__like-icon')].indexOf(t);
        const counter = document.querySelectorAll('.photos__like-count')[index];
        const count = counter.textContent;
        counter.textContent = t.classList.toggle('active') ? -~count : ~-count;
      }
    });
    
    // но если у каждой пары icon-count если отдельный общий предок, то можно и попроще сделать
    document.addEventListener('click', ({ target: t }) => {
      if (t.matches('.photos__like-icon')) {
        t
          .closest('селектор общего предка кнопки и элемента с количеством')
          .querySelector('.photos__like-count')
          .textContent -= t.classList.toggle('active') ? -1 : 1;
      }
    });

    Назначаем обработчик клика каждой кнопке индивидуально:

    const toggleLike = function({ target: t }) {
      this[t.dataset.index].innerText -= [ 1, -1 ][+t.classList.toggle('active')];
    }.bind(document.querySelectorAll('.photos__like-count'));
    
    document.querySelectorAll('.photos__like-icon').forEach((n, i) => {
      n.dataset.index = i;
      n.addEventListener('click', toggleLike);
    });
    
    // или, при наличии отдельных общих предков у каждой пары .photos__like-icon и .photos__like-count
    const toggleLike = ({ target: t }) => t
      .closest('селектор общего предка кнопки и элемента с количеством')
      .querySelector('.photos__like-count')
      .innerText -= t.classList.toggle('active') ? -1 : 1;
    
    for (const n of document.querySelectorAll('.photos__like-icon')) {
      n.addEventListener('click', toggleLike);
    }
    Ответ написан
    Комментировать
  • Как сделать фильтрацию по датам?

    0xD34F
    @0xD34F Куратор тега JavaScript
    function filterByMinMax(arr, [ min, max ], key = n => n) {
      const getVal = key instanceof Function ? key : n => n[key];
      return arr.filter(n => {
        const val = getVal(n);
        return (min == null || min <= val) && (max == null || val <= max);
      });
    }
    
    
    const d1 = filterByMinMax(chartPoints, [ new Date('2019-02-19') ], n => new Date(n.date));
    const d2 = filterByMinMax(chartPoints, [ , '2019-01-23' ], n => n.date);
    const d3 = filterByMinMax(chartPoints, [ '2019-02-12', '2019-02-26' ], 'date');
    Ответ написан
    2 комментария
  • Как отследить изменение значения в переменной?

    sergiks
    @sergiks Куратор тега JavaScript
    ♬♬
    Если есть возможность изменить код создания этой переменной..
    Например, вместо
    var a = 'QnA.habr.com';
    написать
    Object.defineProperty(this, 'a', {
        set: function(v) {console.log('Изменяют!'); this.value = v;},
        value: 'QnA.habr.com'
    });
    то теперь любое изменение значения переменной вызовет панику в консоли:
    a = 'StackOver...';
    // Изменяют!


    Upd. выяснилось, вопрос был совсем про другое )
    Ответ написан
  • Почему данном случае теряется контекст this?

    Aetae
    @Aetae Куратор тега JavaScript
    Тлен
    Простой ответ:
    Берём метод:
    метод = function(){
      console.log(this)
    };
    и(не важно как) пихаем его в какие-то объекты.
    Получаем:
    хрень.метод() // this - хрень
    хрень.кишки.метод() // this - хрень.кишки
    метод() // this - window
    
    хрень.метод.call(хрень.кишки) // this - хрень.кишки
    метод.call(хрень.кишки) // this - хрень.кишки
    метод.call(null) // this - null
    
    элемент.addEventListener('оппа', хрень.метод) //  this -элемент
    элемент.addEventListener('оппа', метод) //  this -элемент
    элемент.addEventListener('оппа', хрень.кишки.продукт.метод) //  this -элемент

    По сути this для фукции - это то, что идёт перед точкой, кроме тех случаев когда он переопределён явно. Всё, никакой эзотерики.)

    fn.call(!this ? this : obj) - это чушь скорее всего. Если this - falsy, то ставим его как this при вызове функции fn, иначе ставим obj. Falsy this может быть только при явном указании(или в strict режиме, при вызове функции напрямую("без точки перед ней")), и скорее всего передача пустого this в таком случае просто сломает выполнение fn.

    Ну ещё следует упомянуть стрелочную фукнцию:
    метод = () => {
      console.log(this)
    };
    это можно считать за явное указание this, потому что this тут всегда привязан тот, что был при создании стрелочной функции, независимо от того как и откуда её вызывают.
    Ответ написан
    3 комментария
  • Почему рекурсия не работает?

    0xD34F
    @0xD34F Куратор тега JavaScript
    Это конечно круто - публиковать код, не говоря при этом ни слова о том, что он делает, и просить найти в нём косяки. Поступлю симметрично: вот вам код рабочий - сравнивайте со своим, думайте:

    const digital_root = num => num > 9
      ? digital_root([...`${num}`].reduce((acc, n) => acc + +n, 0))
      : num;
    Ответ написан
    1 комментарий