Ответы пользователя по тегу JavaScript
  • Объявление обработчика событий в React через упрощенный синтаксис - что делает эта строка кода? Как гуглить подробности об этом?

    maxfarseer
    @maxfarseer
    https://maxpfrontend.ru, обучаю реакту и компании
    > Но нет const.
    Вы объявляете МЕТОД (по теории: если свойство объекта - функция, то такое свойство называется методом), поэтому здесь не должно быть const.

    По старому стилю:
    var myObj = {
      name: 'Toster', // корректно, это свойство объекта
      myFunction: function() { ... }, // корректно, это метод объекта
      var myAnotherFunction: function() { ... } // не корректно, так писать нельзя, следовательно, и const не нужен
    }
    Ответ написан
    3 комментария
  • Почему при изменении состояния в redux не рендерится компонент?

    maxfarseer
    @maxfarseer
    https://maxpfrontend.ru, обучаю реакту и компании
    Чего-то здесь не хватает... логика поиска проблемы правильная. Если в вашем редьюсере в консоль падает то, что нужно, значит следуйте дальше: в компонент, где этот редьюсер подключен и смотрите внутри mapStateToProps так же с помощью консоли, изменились данные или нет. Правильно ли вы их подключили и т.д. (получается вам надо проверить и SideBar и SideBarChat)
    Ответ написан
  • Как сделать модальные окна для карточек товаров?

    maxfarseer
    @maxfarseer
    https://maxpfrontend.ru, обучаю реакту и компании
    React-modal хорошая библиотека, ничего лишнего, я бы рекомендовал оставить ее.
    Как сделать модалку:
    на том уровне, где у вас отрисовывается каталог, или даже выше - вы рисуете модальное окно и ему передаете признак, по которому оно открыто, например: isProductModalOpen (true / false). Этот код находится в "контейнере", приконекченном к redux.

    Далее при клике на кнопку подробнее, вы бросаете экшен OPEN_PRODUCT_MODAL + айдишник товара (который будете запрашивать с сервера) или + всю инфу о товаре, если она у вас уже есть и вам ничего не нужно запрашивать.

    Редьюсер, отвечающий за модальные окна принимает этот экшен и обрабатывает. В частности устанавливает значение, на которое вы опираетесь в контейнере и делаете true для флага isProductModalOpen

    По закрытию модалки - так же улетает экшен, который обрабатывается в редьюсере и признак isProductModalOpen ставится равным false.

    Готово!

    Такой подход позволяет делать несколько модальных окон разных типов.
    Ответ написан
    3 комментария
  • Для чего нужны imutable данные в React?

    maxfarseer
    @maxfarseer
    https://maxpfrontend.ru, обучаю реакту и компании
    Нет профита, не заморачивайтесь.
    Когда "профит" от immutable будет маячить на горизонте, вы уже будете к этому готовы (либо столкнетесь с какой-то проблемой и выйдете на иммутейбл, либо просто повысите теоретическую базу / сложность задачи). Насколько я понимаю, с использованием immutable и без использования .toJS() - поиск в структуре ваших данных будет производиться быстрее.

    p.s. если найду видео добавлю, там была презентация. пока не нашлось.
    Ответ написан
    Комментировать
  • Как исправить код React и использовать babel?

    maxfarseer
    @maxfarseer
    https://maxpfrontend.ru, обучаю реакту и компании
    import React, { Component } from 'react';
    
    class SearchBar extends Component {
      constructor(props) {
        super(props);
    
        this.state = { term: ' ' };
      }
    
      render() {
        return ( // в круглых скобках возвращаем, если более 1й строки
          <div>
            <input onChange={event => this.setState({ term: event.target.value })} />;
          </div>
        )
      }
    }
    export default SearchBar;
    Ответ написан
    1 комментарий
  • Как определить с какой страницы перешли?

    maxfarseer
    @maxfarseer
    https://maxpfrontend.ru, обучаю реакту и компании
    Откуда берется название?
    По факту откуда - не важно. Важно, там где оно есть его передать. Если это title страницы, можно вытащить его стандартным методом (document.title). Можете хранить одно значение "предыдущая страница" или всю историю брождений по вашим "страницам" в редьюсере или sessionStorage (если без redux или не хотите засорять), а класть данные туда с помощью коллбэка в onpopstate

    Следовательно, если у вас redux - то нужно писать так:
    window.onpopstate = function(event) {
      sendLastPage(document.location, document.title);  // ваш_экшен_крейтор(данные_для_передачи)
    };

    Если без redux - то аналогично, складывая в sessionStorage
    Ответ написан
    Комментировать
  • React form validation with refs?

    maxfarseer
    @maxfarseer
    https://maxpfrontend.ru, обучаю реакту и компании
    Если вы будете использовать ref, то значит вы будете иметь доступ к DOM элементу, значит и валидацию надо делать "дедовским" способом, через навешивание обработчиков onChange на все ваши ref'ы (на всю вашу форму тоже получится, зависит от задачи).

    Ref имеет смысл использовать, тогда когда не хотите использовать state, потому что от частого изменения в state у вас будут постоянные перерисовки компонента. Это подойдет для каких-то громадных и тяжелых форм. В обычных ситуациях, небольшой компонент формы без тяжелой логики перерисовывается мгновенно.

    Основы по браузерным событиям (learn.javascrip.ru).
    Ответ написан
    Комментировать
  • Все ли приложение будет ререндерится, если измениться какой то внутренний(где то в приложении) state одного из компонентов?

    maxfarseer
    @maxfarseer
    https://maxpfrontend.ru, обучаю реакту и компании
    Разумеется что нет. Рендерится (перерисовывается) только "та часть" (тот компонент), в которой были изменены пропсы/стейт + все дети если в них нет оптимизаций (например, они могут быть сделаны как stateless, pureComponent или иметь shouldComponentUpdate - тогда перерисовываться не будут при описанных условиях).

    вижу обновили вопрос: да, только футер.
    Ответ написан
    2 комментария
  • Как добавить поле в Record в immutable.js?

    maxfarseer
    @maxfarseer
    https://maxpfrontend.ru, обучаю реакту и компании
    case ADD_PRODUCT_TO_CART_SUCCESS: {
      return state.setIn(["entities", payload.productUid], {...payload.product, count:  ВАШЕ_КОЛИЧЕСТВО});
    }

    В этом коде мы берем все что было в payload.product и по 1 полю добавляем в новый объект ( фигурные скобочки = новый объект), а так же добавляем поле count. Количество (count) вы так же, наверняка, будете передавать в экшене. Получится: count: payload.count (или как вы назовете поле в вашем экшене...)

    Пример:
    { type: ADD_PRODUCT_TO_CART_SUCCESS,
        payload: { productUid, product, count: ваше_количество } // сюда count можно передавать из функции с помощью которой ваш экшен был создан...
      }
    Ответ написан
    2 комментария
  • Что такое side эффект?

    maxfarseer
    @maxfarseer
    https://maxpfrontend.ru, обучаю реакту и компании
    Sideeffect - это что-то, что может повлиять на "чистоту" вашей функции. Редьюсер же - функция. Чистая функция, это значит такая, что если ей на вход подать одни и те же параметры, то результат будет всегда один и тот же.

    Пример: есть у вас в localStorage имя пользователя. И вы в коде пишите, что-нибудь такое:
    case SET_DISPLAY_NAME: {
      return {
        ...state,
        name: window.localStorage.getItem('name') ? window.localStorage.getItem('name') : action.payload,
      }
    }


    Следовательно, если вы подадите на вход функции, имя Вася, то оно вам вернет Васю только если "в sideeffect локал_сторадже" нет ничего. Здесь вы не можете быть уверены, что если подать Васю, вам всегда вернется Вася.

    По примеру с комментариями - не думаю что хороший пример. Айдишники генерировать будет бэкэнд ваш. Вы добавляете новый комментарий путем отправки его на сервер, с сервера приходит статус "ОК" и ваш комментарий уже с айдишником.

    Бывает, что айдишники нужно генерировать самому, тогда они отлично генерятся в acftionCreator'ax. Например, делаете вы систему уведомлений, и у каждого уведомления должен быть свой id (например, тут сервер вам не нужен, вы ничего туда не отправляете, просто визуальная часть). В таком случае, я бы не стал генерировать id через middleware, а просто делал бы это в "экшенах".

    Тем не менее, с генерацией айди все тоже самое, что и с localStorage. Вы не уверены, что подав на вход: имя, текст комментария и почту - получите ТОТ же результат, что и в прошлый раз с такими же входными параметрами (айдишники то разные будут!)
    Ответ написан
    3 комментария
  • Как в React сделать динамическую подгрузку контента?

    maxfarseer
    @maxfarseer
    https://maxpfrontend.ru, обучаю реакту и компании
    Если вы рисуете новые данные через .map и внутри map у вас отрисовывается компонент, то:
    а) написать компонент в functional (stateless) стиле
    б) написать компонент через наследование класса от React.PureComponent
    в) добавить shouldComponentUpdate

    В таком случае у вас будут дорисовываться только ново-пришедшие данные в комонент-родитель.

    Если у вас внутри map сразу верстка, то сделайте компонент и затем на выбор а/б/в выше.

    Документация
    Ответ написан
    1 комментарий
  • Как изменить состояние определенного объекта в списке React?

    maxfarseer
    @maxfarseer
    https://maxpfrontend.ru, обучаю реакту и компании
    В общем случае вам нужно либо содержать в стейте состояния каждого из этих объектов, либо сделать каждый элемент списка отдельным компонентом (компонент то будет один и тот же, просто рисоваться будет с разными данными, следовательно и state будет отдельный у каждого, а класс как я вижу вы уже умеете менять). Мне больше нравится второй вариант, так как при нем у вас в списке будет перерисовываться только маленький кусочек, а не весь список целиком.

    Взаимодействовать с родителем можно через функции в props.
    Ответ написан
  • Как можно улучшить этот код для маштабируемости?

    maxfarseer
    @maxfarseer
    https://maxpfrontend.ru, обучаю реакту и компании
    Я за вас всю работу делать не хочу, заодно хочу мотивировать вас учиться. Так можно переписать onClick
    onClick(showMapName) {
          if (this.state[showMapName]) {
            this.setState({ [showMapName]: false, [showMap1+'Value']:"Открыть карту"})
          } else {
            for (let key in this.state) {
              let nextState = {}
              
              if (key.indexOf('showMap') !== -1) {
                nextState[key] = false // все showMap делаем false
              } 
    
              nextState[showMapName] = true
              nextState[showMapName+'Value'] = 'Закрыть карту'
            }
            this.setState(nextState)
          }
        }


    Вам нужно разобраться, что значит запись через object['property'+value]... здесь

    Второе запись for...in

    Это вас должно натолкнуть на мысль, что вам нужно из render метода передать в функцию аргумент, как это сделать и тд тп. Сама отрисовка должна проходить через цикл/map/и прочий вариант генерирования. Суть-то будет прежняя, нужно повторяющиеся элементы выносить в аргументы функции / в переменную в шаблоне.
    Ответ написан
  • Как изменить какие либо данные по клику?

    maxfarseer
    @maxfarseer
    https://maxpfrontend.ru, обучаю реакту и компании
    Рендер вызывается автоматически в случае:
    - изменения state
    - изменения props
    - forceUpdate (мне ниразу еще не приходилось использовать)

    Так что, да, правильно понимаете (если говорим именно о "перерендерилось"). А то, можно докопаться, что при наличии желания, можно в обход React просто через доступ к DOM поменять src картинки и тд тп (вряд ли это нужно в этом ответе, однако возможность такая есть).
    Ответ написан
    Комментировать
  • Можно ли при обработке события submit формы, узнать введённые данные?

    maxfarseer
    @maxfarseer
    https://maxpfrontend.ru, обучаю реакту и компании
    Конечно, можно!
    Все что есть на странице - может быть вытянуто через JS. Будь то это нативный запрос, типа getElementById или обработка заранее приготовленного стейта, или доступ по ref ссылке...

    p.s. вопрос не самый корректный, нужно больше деталей.
    Ответ написан
    Комментировать
  • Как переписать action в компоненте?

    maxfarseer
    @maxfarseer
    https://maxpfrontend.ru, обучаю реакту и компании
    Понять бы еще зачем этот перенос?

    Тем не менее, если вы хотите использовать dispatch внутри ваших экшенов, можете взять middleware redux-thunk, тогда сможете записать:

    export const handleFilters = (type, val) => {
      return (dispatch, getState) => {
        switch (type) {
        case "input":
          dispatch({
            type: FILTER_BY_INPUT,
            payload: val
          });
        case "time":
          ...
        }
      }
    };
    Ответ написан
    2 комментария
  • Как написать тест для валидации, react/redux?

    maxfarseer
    @maxfarseer
    https://maxpfrontend.ru, обучаю реакту и компании
    Подкину теории: вы хотите протестировать функцию. Ваша функция чистая ( то есть выдает один и тот же результат для одних и тех же входных параметров, иначе _аргументов_ функции). Следовательно тестировать такую функцию просто.
    А) вы импортируете функцию в своем файле с тестами
    Б1) вызываете ее без values.value - ожидаете, что errors.value = 'Please enter value'
    Б2) вызываете ее с values.value === props.initialValues.value и ождаете, что будет errors.value = 'Please enter a new value'

    то есть, вы сами описываете в первом it вашего теста объект values, во втором it описываете values и props. Ваш тест можно описать так: "вы предполагаете, что если дадите 20 рублей продавцу, он выдаст вам батон". Тут так же: вы предполагаете, что если функция validate получит такие-то аргументы (только что вами в этом тесте созданные) - получится такой-то ответ от нее.

    const validate = require('./validate');
    const values = {} // то есть values.value - не существует
    const props = {} // для первого теста на существование значения, нам не важно какие тут значения props
    test('покажет ошибку, если нет значения', () => {
      expect(validate(values, props)).toBe('Please enter value');
    });


    Второй тест вам на домашнее задание.

    p.s. я писал в ответе it, потому что привык, что тесты пишутся внутри it, но сейчас в доке jest вижу, что они используют test ...
    Ответ написан
    3 комментария
  • Контекст функции?

    maxfarseer
    @maxfarseer
    https://maxpfrontend.ru, обучаю реакту и компании
    В конструкторе можете "прибить":
    this.getMouse = this.getMouse.bind(this)
    с помощью оператора bind ваш метод класса (getMouse) всегда будет вызываться в контексте this (которая в момент бинда ссылается на ваш класс)
    Ответ написан
    4 комментария
  • Как реализовать отправку файла на сервер на чистом JS?

    maxfarseer
    @maxfarseer
    https://maxpfrontend.ru, обучаю реакту и компании
    На днях долго ковырялся с нативными fetch + formData для загрузки файла с формы. Как вы знаете, для того, чтобы браузер посчитал content-length и все такое нужен заголовок Content-type: multipart/form-data… в итоге, путем долгих поисков было найдено, что если использовать нативный fetch (не jquery.Ajax, не суперагент, isomorphic-fetch и другие, а именно нативный) - то заголовок Content-type устанавливать (внимание) не нужно.

    Поэтому если есть возможность использовать нативный fetch (смотрите поддержку браузерами) - то все получится.
    Ответ написан
    Комментировать