Ответы пользователя по тегу React
  • Какую архитектуру выбрать для приложения типа Chat, Slack?

    maxfarseer
    @maxfarseer
    https://maxpfrontend.ru, обучаю реакту и компании
    Подскажу ответ только на 1й вопрос: Redux удобнее чем простой Flux, как по мне. У flux нужно много чего держать в голове... что куда подписано и тд тп. А у Redux - store один и этим удобно.

    Ну и докучи закину еще 0.5 на второй.. Реакт-роутер в контексте (следовательно в пропсах) прокидывает много полезной информации. Просто поставьте его, и посмотрите что он передает в компоненты. На основе этих данных сможете сделать выбор, нужен вам он или нет.
    Ответ написан
    1 комментарий
  • Как вставить компонент по нажатию на кнопку?

    maxfarseer
    @maxfarseer
    https://maxpfrontend.ru, обучаю реакту и компании
    Вам не нужно напрямую работать с DOM'ом как это часто было в jquery коде.
    Подумайте следующим образом: у вас есть изменяемое состояние (разное колиество "тудушек" для списка дел) - его можно (а в вашей задаче, думаю и нужно) хранить в state компонента (например в this.state.todos = [ todo1, todo2, todo3 ...])
    В render функции вам нужно пробегаться по this.state.todos и генерировать разметку...

    По кнопке на добавление, вам нужно устанавливать в this.state.todos новый массив, в котором будет на один элемент больше. При этом, так как state изменится, у вас вызовется функция render, а так как в ней идет генерация разметки в зависимости от того, что лежит в this.state.todos - то вы получите на 1 элемент больше. И так по кругу.

    Аналогично реализуется и удаление и редактирование. Вы всегда изменяете что-то в state, реакт перерисовывает для вас компонент и его потомков - вы получаете актуальное состояние.
    Ответ написан
    6 комментариев
  • Почему при добавлении Input теряются введенные данные в других Inputs?

    maxfarseer
    @maxfarseer
    https://maxpfrontend.ru, обучаю реакту и компании
    Ситуация следующая:
    По кнопке add вызывается функция addPropertiesToArray, вы внутри в newArrays имеете: {Registrations:2} и это устанавливаете в state.

    После изменения state, само собой вызывается метод render, внутри которого у вас вызывается функция propertiesParser

    Это функция идет по properties и отрисовывает заметку. У вас в этот момент нет никакой информации, что было введено в inputs, вы это никуда не сохранили, а ре-рендер вызвали (так как state изменили в addPropertiesToArray), следовательно ваши MyInput компоненты отрисовались с пустым значением (вы, в разметке так и указываете value='' => то есть value = пустая строка).

    Чтобы у вас сохранялись введенные значения, вам нужно их где-то хранить. В вашем случае, я бы хранил их в state, и в input'ax брал бы эти значения. Само собой, в функции addPropertiesToArray, эти бы значения в стейт и добавлял.

    p.s. сам код в рамках этого вопроса не обсуждаем, я вашей задумки не понял, мне кажется слишком сложно написано.
    Ответ написан
    2 комментария
  • Универсальный fetch, очень большое количество запросов, с разными условиями, как написать правильно?

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

    p.s. судя по вашему коду вы так и делаете. Если будет удобно разбивайте функцию на более мелкие повторяющиеся кусочки и т.д. (но вижу, что и это уже тоже делаете).
    Ответ написан
    2 комментария
  • SessionStorage в React/Redux?

    maxfarseer
    @maxfarseer
    https://maxpfrontend.ru, обучаю реакту и компании
    внутри какой-то функции, где вы планируете сохранять:
    window.sessionStorage.setItem('localCheck', 'true') (или false)


    в вашем инпуте:
    <input
         checked={window.sessionStorage.getItem('localCheck') ? true : false } // или 'checked' : false не помню точно,
         className="local_checkBox"
         type="checkbox"
         onChange={() => this.clickOnCheckBoxD(params)}/>
    Ответ написан
    Комментировать
  • Как постоянно обновлять данные при помощи componentDidMount?

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

    Рекомендую использовать в вашем случае componentdidupdate (разобраться что это за "лайфхук").
    Ответ написан
    Комментировать
  • Как прокачаться в react/redux?

    maxfarseer
    @maxfarseer
    https://maxpfrontend.ru, обучаю реакту и компании
    Запилить любой проект, в котором будут:
    1) авторизация
    2) роутинг (доступ к некоторым страницам закрыт для не авторизованных)
    3) динамическая подгрузка данных
    Ответ написан
    3 комментария
  • Как сделать такой роутер на react?

    maxfarseer
    @maxfarseer
    https://maxpfrontend.ru, обучаю реакту и компании
    Вопрос можно перефразировать так:
    1) можно ли в реакте написать какой-то динамический шаблон
    2) в зависимости от чего в моей задаче изменять шаблон

    Ответы:
    1) да, можно
    2) можете завязаться, например, на window.location.pathname . Если там /auth - рисуете шаблон + такой-то набор инпутов или чего вам нужно, если там /test - то другой. Так же можно сразу в constructor в state установить какие-то параметры, на основе которых вы будете отображать шаблон и другие разные варианты.

    В render функции это может выглядеть как-то так:
    ...
    render() {
      let template
      if (window.location.pathname.indexOf('auth') !== -1) {
        template = <div>это auth</div>
      } else {
        template = <div>это не auth</div>
      }
      return template
    } 
    ...
    Ответ написан
    Комментировать
  • Как сделать Input disabled?

    maxfarseer
    @maxfarseer
    https://maxpfrontend.ru, обучаю реакту и компании
    Необходимо, чтобы атрибут disabled у input'a реагировал на значение в другом. Если оба инпута в одном компоненте, то можете использовать state, и смотреть если в state первого инпута есть значение, то второй disabled, примерно так:
    <FieldGroup
          id="formControlsText"
          type="text"
          label="Text"
          placeholder="Enter text"
          disabled={this.state.myOtherInputValue1}
        />
    Ответ написан
  • Как сделать onChange функцию через redux?

    maxfarseer
    @maxfarseer
    https://maxpfrontend.ru, обучаю реакту и компании
    export function onChangeUser(value, name) {
      return {
        type:     login.ON_CHANGE_USER,
        fieldName: name,
        value: value
      };
    }
    ...
    case loginActions.ON_CHANGE_USER:
      return {
        ...state,
        [action.fieldName]: action.value
    }
    Ответ написан
    2 комментария
  • Как реализовать шаблонизатор на ReactJS?

    maxfarseer
    @maxfarseer
    https://maxpfrontend.ru, обучаю реакту и компании
    На первый вопрос:

    Оборачиваете все роуты в layoutWithSidebar компонент, в котором есть меню левое и в зоне контента this.props.children
    Активная ссылка (гугл).
    Пример, для роутера 3й версии:
    //компонент NavLink для удобства
    export default class NavLink extends Component {
      render() {
        return <Link {...this.props} activeClassName='active'/>
      }
    }
    ...
    <NavLink to='/url'>NAME</NavLink>
    Ответ написан
    2 комментария
  • Как загрузить изображение в canvas?

    maxfarseer
    @maxfarseer
    https://maxpfrontend.ru, обучаю реакту и компании
    Вы можете обратиться к canvas'у через: this.refs.canvasA, далее работайте как обычно, реакт тут уже не должен фигурировать в вопросе. (то есть, вызываете getContext, вызываете drawImage .... )
    Пример (без реакта).
    Ответ написан
    1 комментарий
  • Как лучше организовать работу с Canvas в React/Redux?

    maxfarseer
    @maxfarseer
    https://maxpfrontend.ru, обучаю реакту и компании
    "canvas мутирует напрямую элементы dom" - не совсем понятно, что имеется ввиду. На canvas происходит рисование. Дом не изменяется, изменяется что-то внутри canvas. Следовательно, чтобы к этому "канвасу" (имеется ввиду сам тэг) обратиться, нам понадобиться ref. Например: <canvas ref='myCanvas' width={180} height={30} />.
    Второй вопрос, тоже не совсем понятен, что имеется ввиду под "концепцией и совместимостью"? Так как у вас есть ссылка на "канвас" через this.refs.myCanvas - можно далее вытащить context, с помощью getContext и уже дальше работать.

    Пример компонента (в зависимости от пришедших данных, рисует столбики повыше, пониже..)
    export default class SomeBars extends Component {
      componentDidMount() {
        this.drawBars(this.props)
      }
      drawBars(props) {
        const { data } = props
        const canvas = this.refs.canvas
        const ctx = canvas.getContext('2d')
        ctx.clearRect(0, 0, canvas.width, canvas.height)
    
        const tempData = data ? data.slice(0,60) : []
    
        tempData.forEach((item,index) => {
          ctx.fillStyle = 'rgba(3,169,244,1)'
          ctx.fillRect(index*3, 30, 2, -(item/2))
        })
      }
      render() {
        return <canvas ref='canvas' width={180} height={30} />
      }
    }


    Если же речь, про canvas и поддержку тасканий мыши и всяких крутых штук (например, как умеет fabric.js) - то можно почитать на SO

    Так же, гугл как обычно, выдает несколько ссылок, например.
    Ответ написан
    Комментировать
  • Можно ли декорировать redux connect или как отписаться от redux store?

    maxfarseer
    @maxfarseer
    https://maxpfrontend.ru, обучаю реакту и компании
    Не знаю зачем, но на вопрос "Как отписаться от redux store, когда демонтируется?" ответить легко - использовать componentWillUnmount

    p.s. стоит прочитать полностью - the component lifecycle
    Ответ написан
  • Как правильно передать action в reducer из компонента?

    maxfarseer
    @maxfarseer
    https://maxpfrontend.ru, обучаю реакту и компании
    export default function rootReducer(state = [], action) {
        console.log(action);
        if(action.type === 'BUTTON_CLICK'){
            return[
            ...state,
                action.book
            ]
                store.dispatch(state) // выкинуть отсюда.
        }
        return state;
    }


    В компоненте, используйте state, в нем храните name и author. По клику на кнопку, вам нужно вызвать ACTION. Скорее всего он вам придет из родителя-контейнера (компонента, который присоединен к store, с помощью функции connect).

    Inputs переписать можно так:
    export default class Inputs extends Component {
        constructor(props) {
            super(props)
            this.onAuthorChange = this.onAuthorChange.bind(this)
            this.onNameChange = this.onNameChange.bind(this)
            this.takeVal = this.this.takeVal.bind(this)
            this.state = {
                author: '',
                name: '',
            }
        }
        onAuthorChange(e) {
            this.setState({ author: e.target.value })
        }
        onNameChange(e) {
            this.setState({ name: e.target.value })
        }
        takeVal() {
            this.props.addItem({ // имя, под которым вы передали свой экшен в качестве пропса от родителя
                author: this.state.author,
                name: this.state.name,
            })
        }
        render() {
            const {author, name} = this.state
            return (
                <div className="app__enter">
                    <div className="inputs-bock">
                        <input onChange={this.onAuthorChange} className="inputs-book__author" placeholder="Автор" type="text" value={author}/>
                        <input onChange={this.onNameChange} className="inputs-book__name" placeholder="Название" type="text" value={name}/>
                    </div>
                    <div className="button-wrap">
                        <button onClick={this.takeVal}>Добавить книгу</button>
                    </div>
                </div>
            )
        }
    }


    Конечно, так как код функций onAuthorChange и onNameChange одинаковый, его можно уместить (и очень просто) в одной функции...

    Ваш "приконекченый родитель" может выглядеть так:

    import React, { Component } from 'react'
    import Inputs from '../components/Inputs'
    import { connect } from 'react-redux'
    
    import {
      addItem,
    } from '../../actions/UserActions'
    
    class InputsContainer extends Component {
      render() {
        return <Inputs addItem={this.props.addItem} />
      }
    }
    
    const mapStateToProps = (state) => ({})
    
    const mapDispatchToProps = (dispatch) => ({
      addItem: (params) => dispatch(addItem(params)),
    })
    
    export default connect(mapStateToProps, mapDispatchToProps)(InputsContainer)


    p.s. доки читать нужно, поддерживаю. ДЗ: переименовать addItem в пропсах и вызвать его внутри takeVal. Сделать из 2х функций обработчиков изменений в инпутах - одну.
    Ответ написан
    1 комментарий
  • Передача массива объектов в component?

    maxfarseer
    @maxfarseer
    https://maxpfrontend.ru, обучаю реакту и компании
    Вы не передаете в JobsList никаких props, следовательно this.props.Jobs = undefined.
    Выносите ваши "джобсы" в тот же файл где export default App, и пишите:
    return (
          <div>
            <JobsList Jobs={jobs} />
          </div>
        );
    Ответ написан
    Комментировать
  • Как в react spa грамотно реализовать разделение прав?

    maxfarseer
    @maxfarseer
    https://maxpfrontend.ru, обучаю реакту и компании
    С помощью роутинга react-router, например. В 4й версии думаю так же, но речь про 3ю.
    Часть роутов, оборачивается в родительский роут, котором идет проверка прав юзера, и далее в зависимости от этого вы рисуете:
    а) разные шаблоны, в которых фигурирует this.props.children
    б) null - если запрещен доступ, или опять же this.props.children - если все ок.

    В "чилдренах" - у вас будут вложенные роуты.

    Проверка прав, надеюсь, в вопрос не входит? Но если входит: то нужно сделать запрос на сервер с этим токеном и получить список разрешенных прав.
    Ответ написан
    Комментировать
  • Когда лучше всего отправлять запрос об изменении текста в input?

    maxfarseer
    @maxfarseer
    https://maxpfrontend.ru, обучаю реакту и компании
    Для этого придумали функцию debounce
    onChange={debounce(this.onInputChange, 300)} // будет вызываться не чаще чем раз в 300 ms
    Ответ написан
    1 комментарий
  • Правильная ли логика работы приложения на react/redux?

    maxfarseer
    @maxfarseer
    https://maxpfrontend.ru, обучаю реакту и компании
    При нажатии на кнопку генерируется action - тип: "КНОПКА_НАЖАТА" (1), у него в payload (полезной нагрузке, поле можно как угодно называть): какая это кнопка.
    Эти данные обрабатываются в редьюсере (2). Например: было пусто, после КНОПКА_НАЖАТА стало "в".
    Это изменение в редьюсере увидели подключенные (с помощью connect) компоненты. И перерендерились*.(3)

    * - если вы никак не мешаете render'y (например: не передаете тот же объект, или используете какое-то условие в shouldComponentUpdate,)

    ---

    Еще вариант, что это у вас все 1 компонент (либо 1 компонент + дети), и вам не надо гонять данные через store (то есть action + reducer ...), а просто можете использовать state.
    Ответ написан
    Комментировать
  • Как вы организовываете folder structure в medium-to-large size react приложении?

    maxfarseer
    @maxfarseer
    https://maxpfrontend.ru, обучаю реакту и компании
    1f2bd294843d4ddca1bb3dd20cf35a70.jpg
    Какая-то тенденция, возможно.. Хочется как-то все "улучшить", вместо "просто писать, пока не будет проблемы". С чем, конкретно, вы столкнулись, что пришло осознание такое?

    Мне кажется, может где-то в проекте и есть неудобства, но я их не ощущаю. Появилась папка helpers, куда я выношу функции, которые используются в разных других файлах, все остальное осталось так же как и было изначально (в проекте уже 1200+ коммитов, много компонентов/контейнеров).

    p.s. папка locales - там файл перевода, в routes и store - по одному конфиг.файлу.
    Ответ написан
    2 комментария