Ответы пользователя по тегу React
  • React-router пути не работают. Как вылечить?

    maxfarseer
    @maxfarseer
    https://maxpfrontend.ru, обучаю реакту и компании
    Очень похоже на ошибку с "выдачей скрипта", то есть
    scripts.js:1 Uncaught SyntaxError: Unexpected token <

    у вас там не script.js, а index.html отдается. Смотрите в network.
    Описано подробно в туториале по реакт-роутеру на русском
    Ответ написан
    2 комментария
  • Side Effects после исполнения reducer'a?

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

    Не совсем согласен. В action creators тоже можно практически безнаказанно провернуть какой-нибудь side-effect (сохранить токен в localStorage, например, после LOGIN_SUCCESS).
    Ответ написан
    Комментировать
  • React, redux, react-router, react-router-redux, как и где делать редирект после логина?

    maxfarseer
    @maxfarseer
    https://maxpfrontend.ru, обучаю реакту и компании
    Мыслите верно, делать dispatch REDIRECT стоит после dispatch SUCCESS_LOGIN.

    Судя по документации, в action creators (создатель действия, первый блок кода) вы все делаете правильно.

    Далее проверяйте у себя (я приведу код, похожий на ваш):

    1) в месте, где передаете history (обычно это Root/App компонент, то есть родитель всего)
    import { AppContainer } from 'react-hot-loader'
    import React from 'react'
    import ReactDOM from 'react-dom'
    import { Router, browserHistory } from 'react-router' // раз
    import { Provider } from 'react-redux'
    import { routes } from './routes'
    import { syncHistoryWithStore } from 'react-router-redux' //два
    import configureStore from './store/configureStore'
    
    const store = configureStore()
    
    const history = syncHistoryWithStore(browserHistory, store) //три
    const rootEl = document.getElementById('root')
    
    ReactDOM.render(
      <Provider store={store}>
        <AppContainer>
          <Router history={history} routes={routes} /> //четыре
        </AppContainer>
      </Provider>,
      rootEl
    )


    2) в месте, где настраиваете объект store (обычно, это функция configureStore)
    import { routerMiddleware } from 'react-router-redux' //раз
    import { browserHistory } from 'react-router' //два
    import { createStore, applyMiddleware, compose } from 'redux'
    import thunkMiddleware from 'redux-thunk'
    import createLogger from 'redux-logger'
    import { rootReducer } from '../reducers'
    
    export default function configureStore() {
      const store = compose(
        applyMiddleware(thunkMiddleware),
        applyMiddleware(createLogger()),
        applyMiddleware(routerMiddleware(browserHistory)), //три (!)
      )(createStore)(rootReducer)
    
      if (module.hot) {
        // Enable Webpack hot module replacement for reducers
        module.hot.accept('../reducers', () => {
          const nextRootReducer = require('../reducers').rootReducer
          store.replaceReducer(nextRootReducer)
        });
      }
    
      return store
    }


    3) combineReducers с роутингом (как у вас и написано)
    import { combineReducers } from 'redux'
    import { routerReducer } from 'react-router-redux' //раз
    import products from './products'
    import login from './login'
    import notificationBar from './notificationBar'
    import provider from './provider'
    
    export const rootReducer = combineReducers({
      products,
      login,
      notificationBar,
      provider,
      routing: routerReducer, //два
    })


    Из вашего вопроса информации недостаточно, но судя по всему вы либо:
    а) передаете не верный history в configureStore
    б) не выполнили syncHistoryWithStore (из пункта 1)

    --- дополнительно ---
    Как вариант посмотрите как сделать редирект после логина в redux с помощью middleware (упрощенный вариант, но хорошо для понимания основ)

    Так же есть "простой" вариант - хранить необходимые данные после логина (токен, свойства юзера, и т.д.) в localStorage. И после логина, делать стандартный browserHistory.push
    Ответ написан
    1 комментарий
  • Как исключить React модули из eslint?

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

    {
      "extends": "eslint:recommended",
      "parser": "babel-eslint",
      "env": {
        "browser": true,
        "node": true,
        "mocha": true
      },
      "plugins": [
        "react"
      ],
      "rules": {
        "no-debugger": 0,
        "no-console": 0,
        "no-case-declarations": 0,
        "new-cap": 0,
        "strict": 0,
        "no-underscore-dangle": 0,
        "no-use-before-define": 0,
        "eol-last": 0,
        "quotes": [2, "single"],
        "comma-dangle": [1, "always-multiline"],
        "jsx-quotes": [1, "prefer-single"],
        "react/jsx-no-undef": 2,
        "react/jsx-uses-react": 1,
        "react/jsx-uses-vars": 1
      }
    }
    Ответ написан
    1 комментарий
  • Верстали ли Вы используя React без какой либо логики?

    maxfarseer
    @maxfarseer
    https://maxpfrontend.ru, обучаю реакту и компании
    Верстают же люди используя "php-конструкции в шаблоне" (ruby/python)...

    То есть, если у в компании четкое разделение, например на бэкэнд-девелопера (и он пишет на питоне) и на верстальщика (что само-собой разумеется), то бэкэнд-девелопер вполне может договориться + научить/объсянить верстальщику как использовать переменные и условия в шаблоне.

    Здесь ситуацию вижу подобную и думаю, что вполне реальна: вы хороший верстальщик и грамотно верстаете, а js-ниндзя сразу пишет логику не изменяя автозаменами все ваши class на className и так далее.
    Ответ написан
    Комментировать
  • Как c помощью React-Router отправить картинку к API и получить ответ?

    maxfarseer
    @maxfarseer
    https://maxpfrontend.ru, обучаю реакту и компании
    Так как вижу в тегах redux - отвечу "в рамках" этого проекта.
    Вам нужно использовать action (действие) - "Отправка_картинки" (и это обычный асинхронный запрос, скорее всего это POST запрос, так?)
    А затем в ответе на ваш асинхронный запрос, генерировать событие "Картинка_отправлена" + данные ответа.
    В редьюсере, вы ловите событие "картинка_отправлена" и добавляете полученные данные в store.

    Причем тут роутер - неясно. Роутинг - это не работа с "урлами" вообще. Это лишь часть работы, так сказать. Грубо говоря, реакт-роутер решает, исходя из url-адреса - какой именно компонент(ы) вам показать.

    По работе с асинхронными действиями в redux можно почитать здесь.
    Ответ написан
    6 комментариев
  • Что делает EventEmitter в react.js?

    maxfarseer
    @maxfarseer
    https://maxpfrontend.ru, обучаю реакту и компании
    Он не то чтобы умеет, тоже что и в Node.js, он и есть 'events' из Node.js
    Ответ написан
    Комментировать
  • Как перейти на другую страницу в React?

    maxfarseer
    @maxfarseer
    https://maxpfrontend.ru, обучаю реакту и компании
    Здесь корректнее было бы сделать так:
    родительский компонент отрисовывает и таблицу и "страницу редактирования", причем у вас в сторе есть переменная, например: edit, если true -> отрисовывается "страница редактирования", если false - отрисовывается таблица.
    При нажатии на строку в таблице - генерируется action (действие), которое как раз в купе с прочими действиями (которые производятся у вас уже) изменяет edit
    Родительский компонент должен быть подписан на store.
    Ответ написан
    Комментировать
  • Как получить данные из Redux State?

    maxfarseer
    @maxfarseer
    https://maxpfrontend.ru, обучаю реакту и компании
    Если у вас есть данные в props - то просто отрисовывайте их в render функции (через this.props.filterState).
    Так как ваш компонент "присоединен" (с помощью connect), значит у вас всегда будут актуальные props.
    Props изменились - вызвается render (по логике работы react) => все отрисовано будет с актуальными данными.
    Ответ написан
    Комментировать
  • Правильно ли я понял суть Flux?

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

    На сколько я понимаю, flux работает по следующему принципу: view подписывается на изменения данных в sotre, если данные store изменились, то перерисовываем view

    Все верно поняли. Осталось лишь добавить, что изменения в store попадают с помощью ACTIONS - так называемых действий.

    p.s. из личного опыта - мне больше понравился redux, основное отличие которого от Flux - объект store всего лишь один! Внес свой вклад материалы на русском здесь.
    Ответ написан
    Комментировать
  • Какие преимущества/недостатки есть у HOC (Higher-order Components)?

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

    Преимущества (разберем это видео[EN]):
    мы описали "функциональность" и добавили ее с легкостью двум нашим компонентам. Следовательно, как минимум два отличных преимущества получили:
    + нет дублирования кода
    + простота в добавлении "функционала"

    Другой хороший пример - "Навигационная ссылка"[RU] (подраздел так и называется - Навигационная ссылка), опять же - мы дали функционал необходимый компоненту. Если этот функционал пригодится где-то еще - мы сможем это устроить.

    Почему порядок, скорее всего не важен - потому что обычно props передаются в стиле "бери все свойства" (...this.props), где ... - spread operator.

    Подытожим:
    используя HOC вы "не изменяете" компонент, который он получает, но добавляете при этом функциональность. Разве уже не круто?)
    Ответ написан
    2 комментария
  • Есть ли курсы,скринкасты или учебники на русском по React js?

    maxfarseer
    @maxfarseer
    https://maxpfrontend.ru, обучаю реакту и компании
    Три курса:
    React.js на русском
    React + Redux на русском
    React + React-router (+ Redux) на русском

    Вся информация текстом, можно скачать в формате книги. Почти к каждой главе приложен исходный код.
    Ответ написан
    Комментировать
  • Express не грузит bundel.js React-а, что не так?

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

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

    1. Произвести аутентификацию
    2. Сохранить токен в компонент
    3. Делать запрос с токеном пользователя.

    Пункт 3 можно улучшить, например не подсвечивать кнопку сделать запрос без токена.
    Ответ написан
  • Как сделать таблицу из аррея через map (приложение на React)?

    maxfarseer
    @maxfarseer
    https://maxpfrontend.ru, обучаю реакту и компании
    import React, { Component } from 'react'
    
    export default class App extends Component {
    
      render() {
        const data = [
          {'name': 'Education', 'number': 33},
          {'name': 'Promotion', 'number': 10},
          {'name': 'Events', 'number': 55 }
         ]
    
        let tableTemplate;
    
        function makeColumns(row) {
          return <td>{row.name} {row.number}</td>
        }
    
        tableTemplate = data.map((row, i) => {
          return <tr key={i}>{makeColumns(row)}</tr>
        })
    
        return (
          <table>
            <tbody>
              {tableTemplate}
            </tbody>
          </table>
        )
      }
    }


    ES5 код ниже

    import React, { Component } from 'react'
    
    export default class App extends Component {
    
      render() {
        var data = [
          {'name': 'Education', 'number': 33},
          {'name': 'Promotion', 'number': 10},
          {'name': 'Events', 'number': 55 }
         ];
    
        var tableTemplate;
    
        function makeColumns(row) {
          return <td>{row.name} {row.number}</td>
        }
    
        tableTemplate = data.map(function(row, i) {
          return <tr key={i}>{makeColumns(row)}</tr>
        });
    
        return (
          <table>
            <tbody>
              {tableTemplate}
            </tbody>
          </table>
        )
      }
    }
    Ответ написан
    2 комментария
  • Где должен быть асинхронный вызов в Redux?

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

    Если подробно, то:
    Асинхронный вызов делается с участием middleware в actions. Таков ответ =)
    По полочкам: обычно используется redux-thunk, код которого очень прост: если actionCreator возвращает ФУНКЦИЮ - то нужно прокинуть в функцию store и dispatch аргументами. Таким образом, из дествий (actions) вы сможете выполнять асинхронные запросы.

    Подробно здесь
    Так же, там весь мини учебник по redux.

    ---

    Для роутинга в ответе на асинхронный запрос - придется использовать еще один middleware, об этом подробно будет написано здесь, раздел: подключаем redux. В данный момент уже почти все закончил, на неделе опубликую.
    Ответ написан
    1 комментарий
  • React и hmr, почему Webpack не пересобирает проект?

    maxfarseer
    @maxfarseer
    https://maxpfrontend.ru, обучаю реакту и компании
    Конфиг несколько староват. Откопал свой конфиг с подобной версией, особых отличий не вижу. Разве что в module include указана директория сразу, а не элемент массива.
    { test: /\.(js|jsx)$/,
            exclude: /node_modules/,
            loaders: ['react-hot','babel?stage=0&optional=runtime&plugins=typecheck'],
            include: path.join(__dirname, 'src/js')
          },


    Полный конфиг здесь (не смотрите что он .hot, это просто для удобства было сделано по не знанию)
    Ответ написан
  • Где сохраняется файл сборки?

    maxfarseer
    @maxfarseer
    https://maxpfrontend.ru, обучаю реакту и компании
    Вы все делаете правильно. Просто вы используете webpack в режиме dev-server (сервера разработчика), когда выполняете команду npm start, поэтому файла физически "как будто бы нет"

    Чтобы получить файл физически, нужно выполнить webpack, но с таким конфигом, возможно этого не произойдет.

    Кстати, чтобы понять, что делает npm start - загляните в package.json, там есть пункт: scripts
    Оттуда видно, что выполняется node server.js, то есть в этом случае npm start === node server.js (можете проверить, запустив из консоли node server.js)

    А уже server.js создает сервер и использует возможности webpack-dev-server
    Подробнее описано здесь
    Ответ написан
    Комментировать
  • В чем проблема с reducer в redux?

    maxfarseer
    @maxfarseer
    https://maxpfrontend.ru, обучаю реакту и компании
    Консоль лог даже не выскакивает?
    Ночью вникать не очень хочется, просто по коду скажу - опечатка в
    resuls: {
          field,
          data
        }


    и лучше использовать payload, а не results. Так "типа" по стандартному соглашению.

    Скинь весь проект на github, и дай ссылку в комментарии.

    p.s. если что про redux на русском здесь
    Ответ написан
  • Как правильно разделить ответственность между состоянием интерфейса и дерева состояния в React и REDUX?

    maxfarseer
    @maxfarseer
    https://maxpfrontend.ru, обучаю реакту и компании
    Слышал что если используешь redux то про функцию setState в большинстве случаев можно забыть.

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