Ответы пользователя по тегу React
  • Как сделать Ajax запрос на React js?

    maxfarseer
    @maxfarseer
    https://maxpfrontend.ru, обучаю реакту и компании
    Или используйте старый xhr (новый fetch тоже норм). В общем, тут суть в том, что ваш вопрос больше о том, как сделать асинхронный запрос в React. Все просто: храните начальное состояние и флаг загрузки в стейте. При запросе обновляйте. Реакт сам все отрисует при изменение стейта.

    Пример (код с одной из глав нового учебника, если интересно инфа в профиле)
    class App extends React.Component {
      constructor(props) {
        super(props)
        this.state = {
          data: [],
          isLoading: false,
        }
      }
      componentDidMount() {
        const xhr = new XMLHttpRequest();
        xhr.open('GET', 'http://localhost:3000/data.json', true); // замените адрес
        xhr.send();
        this.setState({ isLoading: true })
    
        xhr.onreadystatechange = () => {
          if (xhr.readyState !== 4) {
            return false
          }
    
          if (xhr.status !== 200) {
            console.log(xhr.status + ': ' + xhr.statusText)
          } else {
            this.setState({
              data: JSON.parse(xhr.responseText),
              isLoading: false,
            })
          }
        }
      }
      renderProducts() {
        const { data, isLoading } = this.state
        if (isLoading) {
          return <img src='/i/preloader.gif' alt='загружаю...' /> // рисуем прелоадер
        } else {
          return data.map(item => {
            // я здесь отрисываю все через другой компонент, вы же можете просто рисовать сразу верстку для начала
            return <ProductCard key={item.id} name={item.name} price={item.price} quantity={item.quantity} />
          })
        }
      }
      render() {
        return (
          <div className='App'>
            <div className='product-list'>
              {this.renderProducts()}
            </div>
          </div>
        )
      }
    }
    Ответ написан
    1 комментарий
  • Как изменить состояние определенного объекта в списке React?

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

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

    maxfarseer
    @maxfarseer
    https://maxpfrontend.ru, обучаю реакту и компании
    Как теперь сделать так чтобы в состоянии например в модуле users/people хранить всех пользователей которые зарегистрировались

    Посмотреть как в firebase получить всех пользователей и в нужный момент, выполнять запрос за ними.
    Или тут больше вопрос о том чтобы найти в firebase API нужный метод?
    Ответ написан
    4 комментария
  • React + Redux, как создать выпадающий список?

    maxfarseer
    @maxfarseer
    https://maxpfrontend.ru, обучаю реакту и компании
    Теория:
    по щелчку = по действию от пользователя = экшен
    изменить данные в сторе = прокинуть через reducer.

    Далее, раз у вас есть вариант показывать/скрывать дропдаун, то можно это состояние спокойно хранить в state компонента-представления, ибо флаг: показано/скрыто вряд ли нужен другим вашим компонентам.

    Итого: получаем данные от севера, кладем их в соответствующий редьюсер, по щелчку изменяем стейт компонента и показываем/скрываем список, по клику в списке (если такое нужно) - отправляем экшен, который улетает на сервер, и, допустим, сохраняет измененную инфу о юзере - приходит ответ - вы далее сами решаете, класть этот ответ снова в reducer и как-то заставлять на это реагировать UI или нет.

    Когда идет речь, об "отправляем экшен" - это значит из компонента-представления мы вызываем метод (через функцию переданную в качестве пропса) родителя, то есть компоненета-контейнера. В контейнере этот метод должен в итоге вызывать (или сразу быть так передан) "приконекченный" вызов ( внутри функции connect, в качестве аргумента mapDispatchToProps). Если совсем "в наглую делать" для теста, то это store.dispatch.ACTION_CREATOR_NAME

    const UserContainer = connect(
      state => ({
        default_role: state.customerProject.default_role,
        show_role: state.customerProject.show_role,
        roles_user: state.customerProject.roles_user
        
      }),
      dispatch => ({
        anyName: () => dispatch(myActionCreator()) // и затем this.props.myNewActionCreator нужно передать в компонент-представление. Если нужно сделать доп-обработку, то передать метод из контейнера, в котором будет сначала обработка, а потом вызов this.props.myNewActionCreator
      }))(AboutUser)
    ...
    
    const changeRoleUser = () => {
            this.props.anyName()
        }
    ...
    Ответ написан
  • Как можно улучшить этот код для маштабируемости?

    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. вопрос не самый корректный, нужно больше деталей.
    Ответ написан
    Комментировать
  • Как сделать ссылку на страницу с компонентом в react-router?

    maxfarseer
    @maxfarseer
    https://maxpfrontend.ru, обучаю реакту и компании
    Какой у вас роутер? Если четвертый, то должно быть так:
    class App extends React.Component {
      render() {
        return (
          <div>
           <Switch>
              <Route exact path='/' component={Home} />
              <Route path='/signup' component={Registration} />
              <Route component={NoMatch} /> {/* для всех остальных адресов */}
            </Switch>
          </div>
        );
      }
    }


    Чтобы на эту страницу попасть, нужно использовать вместо <a> компонент из RR - <Link to='registration'>Регистрация</Link>

    То есть вы внутри switch выбираете, что показывать! Значит вам еще нужно сделать компонент Home в котором уже разместить кнопку на регистрацию:
    <Link to="/signup" className="btn btn-warning">Регистрация</Link>
    Ответ написан
    Комментировать
  • Должно ли в React всё быть компонентами?

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

    Другое дело, когда у вас изначально SPA приложение на React. Тогда нет никакого смысла шапку/страницы с логотипом и так далее делать не на react. Удобно же, когда все в компонентах.
    Ответ написан
  • В чем разница между Redux и Reflux?

    maxfarseer
    @maxfarseer
    https://maxpfrontend.ru, обучаю реакту и компании
    В общем:
    - redux популярнее (больше работы)
    - redux должен быть стабильнее (так как слишком широкое внимание к себе привлекает)

    Технически: обе библиотеки берут свое начало от реализации flux, но имеют разницу в деталях. Судя по документации reflux - у них тоже (как и flux) несколько store-хранилищ. У redux - store един.

    Суть библиотек одна: однонаправленный поток управления данными. Если говорить простым языком: как управлять всеми данными в приложении: кто-то куда-то кликнул, что-то где-то изменилось.
    Ответ написан
    Комментировать
  • Что такое react на пальцах?

    maxfarseer
    @maxfarseer
    https://maxpfrontend.ru, обучаю реакту и компании
    Вы можете написать все что угодно. Будь это сайт с сундуками cs:go или сервис поиска дешевых билетов. Главное, что React и подобные библиотеки отвечают за "лицевую" часть. Отсюда и слово frontend. Для полноценного сервиса нужен еще бэкэнд.

    Реакт упрощает написание SPA - то есть одностраничного приложения. Это такое приложение, которое не требует перезагрузки окна браузера для брождения по разным экранам.

    Без бэкэнда вы тоже можете написать кучу приложений, если воспользуетесь доступными API.
    Например - вк выдает вам всю инфу по вашим фотографиям. Вы можете найти те, которые были самыми популярными (по лайкам), добавить сортировку по годам, фильтры по 10 / 100 лайков, например.

    Если играете в доту, можете вытащить все свои игры и построить графики... (пример dotabuff)

    И тд тп.
    Ответ написан
    3 комментария
  • Как убрать множественные срабатывания таких событий, как onMouseover, onMouseOver?

    maxfarseer
    @maxfarseer
    https://maxpfrontend.ru, обучаю реакту и компании
    Когда наводится и выходит за рамки, это onmouseenter и onmouseleave (в реакте соответственно: onMouseEnter и onMouseLeave)
    Ответ написан
    Комментировать
  • Flow vs. TS? Нужны ли они для Реакта?

    maxfarseer
    @maxfarseer
    https://maxpfrontend.ru, обучаю реакту и компании
    Flow удобный и минималистичный*, мне нравится с ним работать. Помогает писать код "чуть строже", итого в связке eslint+flow получается чистый и "устойчивый" код. В добавок к этому многие редакторы сразу подсвечивают, что не так.

    * - минималистчный, это мне так кажется по сравнению с TS. в TS нужно разбираться дольше, чем с Flow, хотя это мнение может быть ошибочным, так как flow использую активно, а с TS не работал.
    Ответ написан
    Комментировать
  • Как переписать 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 комментария
  • Как залить Webpack+React приложение на github pages?

    maxfarseer
    @maxfarseer
    https://maxpfrontend.ru, обучаю реакту и компании
    Вам нужен webpack-dev-server на гитхаб пейджс? Если да, то никак.
    На github вы можете залить "билд" вашего приложения: то есть вашу index.html + картинки + стили (css) + скрипты (ваш бандл и все что еще нужно из js).
    Чтобы получить билд, нужно его собрать. То что в результате сборки будет - это и нужно залить на pages.
    Запущенный сервер (на node.js или еще какой) - не будет работать на pages (или есть примеры?)
    Ответ написан
    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 комментария
  • React + Redux: какие преимущества в раздельном подключении каждого контейнера через connect?

    maxfarseer
    @maxfarseer
    https://maxpfrontend.ru, обучаю реакту и компании
    первый вопрос:
    при изменениях в store (глобальном state) у вас будут перерисовываться все компоненты, которые подписаны на эти изменения и в которых нет явного запрета на это через shouldComponentUpdate. То есть, если перерисуется родитель, то потом перерисуются и все его потомки. Класс? (сарказм, разумеется не класс). Поэтому подключение в "субконтейнерах", как вы говорите - продуктивнее: будут перерисовываться только те кусочки (родитель+дети), которые были подписаны на кусок (часть) данных из глобального store.

    второй вопрос: так работает react-redux библиотека и частности функция connect, которая словно "приклеивает" ваши выборочные данные из store в props приконнекченного компонента. (используются возможности свойства рекакт компонентов - context ). Через react dev tools посмотрите, и увидите, что у вас автоматически, в результате работы функции connect, появляется родитель Conneceted(ComponentName) в котором оказываются нужные свойства (через контекст) и которые прокидываются вниз в ребенка (в уже написанный вручную вами компонент) пропсы.
    Ответ написан
    Комментировать
  • Контекст функции?

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

    maxfarseer
    @maxfarseer
    https://maxpfrontend.ru, обучаю реакту и компании
    export const logout = () => {
      sessionStorage.removeItem('auth');
      return {}; <-- забыли экшен свой { type: LOGOUT }
    };
    Ответ написан
  • Как реализовать поведение такого компонента?

    maxfarseer
    @maxfarseer
    https://maxpfrontend.ru, обучаю реакту и компании
    Вам нужно хранить у кнопки в каждом блоке свой идентификатор. Например в data-* аттрибуте. Тогда, когда будете нажимать на кнопку минус, относящемуся к данному блоку, сможете считать у нее этот атрибут и вуаля.

    Пример кнопки:
    <button data-myId='100' onClick={this.minus}>minus</button>

    Пример считывания:
    minus = (e) => {
      console.log(e.currentTarget.dataset.myId) // 100
    }

    Массив с данными ваших "блоков" хранится в state и по минусу + зная айдишник, можно этот "блок" из state удалить (то есть, удалить элемент из массива).

    А рисовать все ваши "блоки" нужно через функцию (скорее всего map), которая проходит по вашим данным в state и отрисовывает их.

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