Ответы пользователя по тегу Redux
  • Как правильно построить архитектуру компонентов react+redux?

    maxfarseer
    @maxfarseer
    https://maxpfrontend.ru, обучаю реакту и компании
    Это как-то неудобно, у меня есть идея чтобы вынести List Item (stuff/:id/comp_7/:item_id) и Subitem (stuff/:id/comp_2/:item_id/sublist/:subitem_id) в отдельные контейнеры.

    Нормальная идея.

    Судя по вашей схеме, каждый элемент с красным текстом (я так понимаю, это роуты) - должен быть контейнером и будет легче.
    Ответ написан
  • Как правильно тестировать Reducer в Jest?

    maxfarseer
    @maxfarseer
    https://maxpfrontend.ru, обучаю реакту и компании
    it(`handle action ${patientActions.ON_CHANGE_PATIENT}`, ()=>{
            expect(reducer(undefined, {
                type: patientActions.PATIENT_INIT_STATE, // тут должно быть patientActions.ON_CHANGE_PATIENT
                payload: {
                    value: '11122',
                    field: 'patient_ur'
                }
            })).toEqual({...defaultStates, patient_ur: '11122'})
        })


    ошибку в этом тесте исправьте, если "пройдет", то думаю дальше все получится. Суть юнит-тестов в том, что вы пишите: было А, применил какую-то функцию (в вашем случае редьюсер), стало Б. Сравнить с В.
    Причем "В" вы описываете сами.
    Ответ написан
  • Какую архитектуру выбрать для приложения типа Chat, Slack?

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

    Ну и докучи закину еще 0.5 на второй.. Реакт-роутер в контексте (следовательно в пропсах) прокидывает много полезной информации. Просто поставьте его, и посмотрите что он передает в компоненты. На основе этих данных сможете сделать выбор, нужен вам он или нет.
    Ответ написан
    1 комментарий
  • Универсальный 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)}/>
    Ответ написан
    Комментировать
  • Как прокачаться в react/redux?

    maxfarseer
    @maxfarseer
    https://maxpfrontend.ru, обучаю реакту и компании
    Запилить любой проект, в котором будут:
    1) авторизация
    2) роутинг (доступ к некоторым страницам закрыт для не авторизованных)
    3) динамическая подгрузка данных
    Ответ написан
    3 комментария
  • Как сделать 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 комментария
  • Как лучше организовать работу с 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 комментарий
  • Правильная ли логика работы приложения на react/redux?

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

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

    ---

    Еще вариант, что это у вас все 1 компонент (либо 1 компонент + дети), и вам не надо гонять данные через store (то есть action + reducer ...), а просто можете использовать state.
    Ответ написан
    Комментировать
  • Лучшая библиотека для asynchronous data fetching?

    maxfarseer
    @maxfarseer
    https://maxpfrontend.ru, обучаю реакту и компании
    Использую isomorphic-fetch
    Ответ написан
    Комментировать
  • Как правильно вывести данные из JSON в React-router/Redux, на новой стр., соответствующие текущему id?

    maxfarseer
    @maxfarseer
    https://maxpfrontend.ru, обучаю реакту и компании
    showInfoPage(e) {
      const id = e.currentTarget.id
      // далее нужно вызвать сам переход
      // я делаю это через push из react-router-redux ( import { push } from 'react-router-redux' )
      // можно прокинуть через dispatch
      dispatch(push('/information/'+id))
    
      //конечно, у вас dispatch скорее всего будет прокинут из props, поэтому финальный вариант
      this.props.dispatch(push('/information/'+id))  
    }
    
    <tr onClick={showInfoPage} id={infos.id}>
         <td key={infos.id}>{infos.id}</td>
         <td key={infos.about}>{infos.about}</td>
    </tr>


    p.s. вместо id, можете использовать data-* атрибуты, и доставать их через e.currentTarget.dataset.*
    Ответ написан
    4 комментария
  • Почему обновляется родительский элемент react+redux?

    maxfarseer
    @maxfarseer
    https://maxpfrontend.ru, обучаю реакту и компании
    ...
    let AppSmallRedux = connect(
        (store) => ({ data: store.reducerAppSmall }), // (1)
        dispatch => ({
            update: () => dispatch({ type: "UPDATE_AppSmall" })
        })
    )(AppSmall);
    ...
    let AppRedux = connect(
        (store) => ({ data: store.reducerApp }), // (2)
        dispatch => ({
            update: () => dispatch({ type: "UPDATE_App" })
        })
    )(App);
    ...


    В пунктах (1) и (2) вы подписывались на весь STORE, следовательно, если он менялся, то у вас на это реагировали все "приконекченные" компоненты. Если подписываться только на "нужный кусочек стора" - то все будет ок.

    Ваш обновленный пример (codepen).
    Ответ написан
    Комментировать
  • Как в приложении react+redux реализовать отправку картинки?

    maxfarseer
    @maxfarseer
    https://maxpfrontend.ru, обучаю реакту и компании
    Почему не можете? Это же тоже обычное поле формы.
    Посмотрел старый проект, где это делал. Было так:
    ...
    const request = require('superagent-bluebird-promise')
    ...
    export function addProduct(formData) {
      return dispatch => {
        dispatch({ type: PRODUCT_ADD_REQUEST })
        if (formData.image) {
          return request.post(`${API_ROOT_V1}/api/v1/products/add`)
            .field('name', formData.name)
            .field('price', formData.price)
            .field('description', formData.description)
            .field('providerId', formData.providerId)
            .attach('image', formData.image, formData.image.name) // добавление картинки
            .then(...) // здесь дальнейшая обработка в случае успеха
        } else { // кейс, когда у товара нет картинки
          return request.post(`${API_ROOT_V1}/api/v1/products/add`)
            .send(formData)
            .then(...)
        }
      }
    }


    В коде компонента formData формирую так:
    ... 
    // (обработчик сабмита формы)
    this.props.addProduct({
          name,
          price,
          description,
          image: findDOMNode(this.refs.image).files[0], // (забираю картинку)
          providerId: this.props.providerId,
        })
    ...
    
    // непосредственно кнопка загрузки файла в форме
    <div className='form-group'>
              <input
                id='productImage'
                type='file'
                name='image'
                placeholder='Image'
                onChange={this.handleChange}
                value={this.state.image}
                data-field-name='image'
                ref='image' />
              <p>Load product image</p>
            </div>
    ...
    Ответ написан
    2 комментария
  • Как правильно обработать Promise redux?

    maxfarseer
    @maxfarseer
    https://maxpfrontend.ru, обучаю реакту и компании
    Судя по коду, вы решили ввязать еще и в это дело redux, значит надо дополнить ваш пример редьюсером и считать данные из него.
    офф.документация
    туториал на ру (устарело, но сама суть не изменилась)
    Ответ написан
    Комментировать
  • Как правильно использовать state в React в связке с Redux?

    maxfarseer
    @maxfarseer
    https://maxpfrontend.ru, обучаю реакту и компании
    Через state и делайте. То, что не нужно никаким другим вашим компонентам (которые, вдобавок, не являются потомками) отлично уживается в state.
    Ответ написан
    Комментировать
  • Переписать часть сайта на react/redux?

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

    Конечно, для этого, нужно будет, чтобы на сервере было REST API (если уже - то писать "отдельный" сервер не нужно, а если нет - то все равно не нужно, но придется писать "отдельный" кусок, в котором будет реализовано это API).

    На react native скорее всего тоже сможете использовать, но я бы сразу так "радужно" не настраивался, ибо с кодом придется повозиться, в любом случае, то что будет написано на бэкэнде уже пригодится для мобильного приложения на любом инструменте.
    Ответ написан
    4 комментария
  • Пример архитектуры большого сайта-SPA?

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

    Супер "полноценных" нет, но где-то тут же на тостере уже всплывала подобная тема. Из давнего (уже) помню soundcloud клиент - статья, github.

    Выложить в open-source рабочее бизнес-приложение - практически невозможно.
    Выложить какую-то его часть, которая сделана хорошо - уже реальнее, по такому типу можно смотреть на хорошие библиотеки (типа react-virtualized). Но опять же, там "архитектуры" по вашему вопросу нет.
    Выложить в общий доступ хороший "учебный" проект - самое реальное. Поэтому может найдется где хорошее платное учебное приложение? А может и бесплатное...

    p.s. все же упирается в деньги/время. Если даже бизнес скажет - "выкладывай куда хочешь", то выложите ли вы свою поделку? Вряд ли, так как написано оно было в стиле "пожалуйста, выкати фичу побыстрее, если потом будет время - порефакторишь". Поэтому просто предлагаю писать по мере своих возможностей, а учиться продолжать там же где и раньше, так как полноценное крепкое приложение в опен-сорсе, это почти миф.
    Ответ написан
    Комментировать
  • Relay замена Redux для React?

    maxfarseer
    @maxfarseer
    https://maxpfrontend.ru, обучаю реакту и компании
    Facebook придумали Flux подход до Redux.
    А потом еще и Relay. Не знаю, смотрели ли они в это время на Redux или нет.
    Ответ написан
    Комментировать