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

    maxfarseer
    @maxfarseer
    https://maxpfrontend.ru, обучаю реакту и компании
    Не могу сказать "хорошо/плохо/как лучше", так как всего примера не вижу, но если хотим сделать "как-то еще", то
    можно использовать объект location

    Например:
    generateClassNames() {
        if (location.href.indexOf('list') {
            return '.wrapper--list'
        }
        ...
    }
    ...
    render()
    ....
    let myClass = this.generateClassNames()
    ...
    <div classNames={myClass}>
    ...


    Так же, для работы с классами, удобно использовать пакет classnames
    Ответ написан
  • Может ли redux искать и возвращать обьект из стейта?

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

    Например, есть некий бэкэнд, который возвращает вам ответ. Вам в компоненте из этого ответа нужна всего пара полей. Следовательно, стоит из редьюсера сразу возвращать только необходимые данные.
    Ответ написан
  • React, redux, middleware какой набор инструментов и библиотек лучше использовать?

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

    Про jquery, я так понимаю вы имеете ввиду $.ajax ? А вот про middleware... (может быть не до конца понимаете, что это такое?)

    По вопросам:
    1. Производительность
    А как в вашей сборке жмется конечный файл?
    сейчас собрал сборку gulp, browserify, babelify, babel + библиотеки redux и react

    Не увидел здесь uglifyJS или что-нибудь подобное...

    Многие собирают webpack'ом, (для продакшен версии используя флаг -p, который в свою очередь.. бинго! Запускает разные "сжималки" кода. Не буду вас путать, но по-моему там тоже uglifyjs)

    2. Стили
    Стили, это стили. Как вам нравится, так и пишите. Собирайте их хоть gulp'ом, хоть webpack'ом... Разницы нет.

    3. Посоветуйте, пожалуйста, сборку и набор библиотек, под задачи которые мне предстоит решить:
    К сожалению, могу только подсказать проверенную на проекте либу для построения графиков (не очень крутая и разных типов графиков не так много, но неплохо настраивается и можно быстро разобраться)

    сегодня наткнулся на мануал использования webpack и gulp одновременно на одном проекте

    Оправдан. Если вам удобно какие-то таски прогонять через gulp, почему нет? Если сможете все, что делаете gulp'ом сделать на webpacke, то используйте только его.

    P.S. По поводу сборок. Брать чужую сборку обычно вредно (так как взяли, запустили, а коснись чего - неизвестно как это работает). Особенно, если сборка большая. Вот хороший пример большой и сложной "сборки". Чтобы понять как там все работает, потребуется порядком времени. А нужно ли будет вам все то, что автор туда накрутил? Поэтому, в качестве ознакомления, можно и посмотреть.

    P.P.S. Даже минимальная create-react-app сборка имеет немало всего интересного "под капотом". Поэтому, я за то, чтобы к сборке подходили осознанно, и лучше своей - придумать сложно. Опять же, "своя" появляется далеко не сразу, поэтому просто начните делать приложение.
    Ответ написан
    Комментировать
  • Как подключать сторонние react компоненты?

    maxfarseer
    @maxfarseer
    https://maxpfrontend.ru, обучаю реакту и компании
    Сложность в том, что архитектура react-проектов разная - в первую очередь, как мне кажется, связанная с redux.

    Как раз таки у "годных" компонентов (или может быть, кому-то ближе "плагинов") нет никакой привязки к тому, как у вас хранятся данные. Правило хорошего тона - ваш компонент, ничего не знает о том, что происходит вокруг, он просто отображает данные и вызывает функции обработчики, которые уже "где-то там" будут эти данные изменять. Считаю, что один самых крутых примеров такого компонента, это react-virtualized

    как можно их публиковать и загружать в проект?

    Так как, это npm пакет, то следовательно, нужно копать в эту сторону (пример). (гугл)
    Ответ написан
    Комментировать
  • Библиотека асинхронных запросов для react?

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

    Есть проект, на бэкэнде elixir+phoenix. Мне в каждом сообщении приходит ref + автоинкреметный id. Следовательно, когда я делаю первый запрос и данные идут долго, а потом второй запрос и данные приходят быстрее, то ref будет больше и я просто в редьюсере игнорирую старый ответ (в стиле, action.ref < state.ref => верни текущий стэйт).

    P.S. если используете сокеты, как вы "замедляете" получение ответа? Мне пришлось попросить "бэкэнд" отвечать медленнее, для тестирования этой проблемы. Так как в chrome devtools в нетворке "замедление" не работало для запросов по сокету.
    Ответ написан
    Комментировать
  • Как динамически добавить компонент в React?

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

    (перевел главный кусок с ответа по ссылке выше)

    // ...
    // SampleComponent - ваш однотипный компонент
    // ...
    
    class Test extends Component {
        constructor(props) {
            super(props)
            this.addChild = this.addChild.bind(this)
            this.state = {
                components: [
                    {
                        id:1, name: 'Some Name'
                    }
                ]
            }
        }
    
        addChild() {
            // Изменение стейта спровоцирует перерисовку
            this.setState(this.state.concat([
                {id:2,name:"Another Name"}
            ]))
        }
        render() {
            return (
                <div>
                    <h1>App main component! </h1>
                    <button onClick={this.addChild}>Add component</button>
                    { // здесь будет отрисовано необходимое кол-во компонентов
                        this.state.components.map((item) => (
                            <SampleComponent key={item.id} name={item.name}/>
                        ))
                    }
                </div>
            );
        }
    }
    Ответ написан
    Комментировать
  • Нужен совет по react и angular?

    maxfarseer
    @maxfarseer
    https://maxpfrontend.ru, обучаю реакту и компании
    Что проще освоить новичку angular или react с redux-ом?

    Мое мнение: разницы нет

    Стоит ли переходить на angular или продолжить изучать react и redux?

    Если пишите, что понимаете angular лучше, то может тогда на нем уже стоит что-то сделать за деньги? По рынку вакансий - реакт догоняет ангуляр. Плюс в вакансиях по реакту конкуренция сейчас пониже (на мой взгляд).

    p.s. из вопроса, не понял каков уровень js... Что можете сделать на js (+ jquery и плагины?)
    Ответ написан
  • Как в ReactJS организовать подключение компонента из другого файла?

    maxfarseer
    @maxfarseer
    https://maxpfrontend.ru, обучаю реакту и компании
    Вам нужно собирать бандл с помощью Wepback / Browserify и т.д. Require / import не сработают, даже если указать text/babel.

    Немного с SO:
    stackoverflow.com/a/36698789/1916578 (почему не работает require/import)
    stackoverflow.com/a/20578692/1916578 (на всякий случай, если вы не используете локальный сервер - здесь есть информация об ошибке и что с этими делать) + локальный сервер легко поднять с помощью http-server
    Ответ написан
    Комментировать
  • Используют ли при работе с Angular, Backbone, VUE и другими структуру из нескольких html-страниц?

    maxfarseer
    @maxfarseer
    https://maxpfrontend.ru, обучаю реакту и компании
    Не практикуют.
    Ответ написан
    Комментировать
  • Часто вижу в коде на сайтах сделанных на react такую конструкцию, что она значит?

    maxfarseer
    @maxfarseer
    https://maxpfrontend.ru, обучаю реакту и компании
    Это просто "продакшен" версия. В ней имена компонентов становятся такими.
    Попробуйте у себя сделать прод. сборку (например, с помощью wepback -p) и посмотрите, что получится.
    Ответ написан
  • Как правильно подключить React к сайту?

    maxfarseer
    @maxfarseer
    https://maxpfrontend.ru, обучаю реакту и компании
    В документации, один из пунктов, что нужно: A compiler such as Babel. It lets you write modern JavaScript code that still works in older browsers.

    Браузер "не умеет import", так сказать. Вам нужно прогонять ваши скрипты, написанные в ES2015 через инструменты, типа babel.
    Ответ написан
    Комментировать
  • Установка react/webpack, в чем проблема?

    maxfarseer
    @maxfarseer
    https://maxpfrontend.ru, обучаю реакту и компании
    Могу предположить, что возможно проблемы в пути (есть пробел у директории Study projects). Попробуйте провернуть все это в директории, в пути до которой нет пробелов.
    Ответ написан
  • Eslint Best practices?

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

    В .eslintrc есть возможность "унаследовать конфиг". Например,

    {
      "extends": "eslint:recommended", // унаследовали от eslint:recommended
      ...
      "rules": { // переопределили/добавили свои правила
        "no-debugger": 0,
        "no-console": 0,
        ...
      }
    }
    Ответ написан
    Комментировать
  • Сортировка данных в react + redux?

    maxfarseer
    @maxfarseer
    https://maxpfrontend.ru, обучаю реакту и компании
    Можно нормализовать данные. По этому поводу, я думаю вам будет крайне полезно посмотреть второй курс[EN] от создателя redux.

    p.s. урок про нормализацию, где рассказывается, как можно решить вашу проблему, но мне кажется, чтобы понять, потребуется посмотреть весь курс.

    p.p.s. полезные ссылки:
    1) https://rajdee.gitbooks.io/redux-in-russian/conten... (может переведут, когда-нибудь)
    2) https://habrahabr.ru/company/hh/blog/310524/ (RU)
    Ответ написан
    1 комментарий
  • Как в React.JS сделать поочередный вывод из массива данных JSON?

    maxfarseer
    @maxfarseer
    https://maxpfrontend.ru, обучаю реакту и компании
    Вам нужно сделать API, которое будет отдавать определенное кол-во записей. Поясню: вам нужно сделать backend, так сказать. Можно написать на node.js / php / python / и т.д. Возможно, есть какой-то готовый сервис для подобных вещей, но я не искал.

    Например: GET запрос на api/loadjson?limit=100&offset=0 (выдай 100, отступ 0, потом будет запрос выдай 100 - отступ 100, выдай 100 отступ 200 и тд), т.е. в теории дело обстоит так: вы загружаете первые N записей и устанавливаете обработчик на window.onscroll (пример тут), далее выбираете через какой интервал в пикселях вы планируете подгружать еще и загружаете еще N записей и так далее.

    Подгрузку осуществляете с помощью xhr (или, если угодно - ajax) запросов (мне нравится isomorphic-fetch)

    Из готовых компонентов, рекомендую react-virtualized. Настройка сперва выглядит трудновато, но это одна из лучших библиотек в плане документации, которую я видел. Есть все! На всякий случай - gitter чат, где есть и сам разработчик (язык EN).
    Ответ написан
    5 комментариев
  • Как реализовать авторизацию пользователя на стеке React Redux Node?

    maxfarseer
    @maxfarseer
    https://maxpfrontend.ru, обучаю реакту и компании
    Пригодится jwt. (гугл)

    В общих словах: вам нужно выдать юзеру токен. С этим токеном юзер будет выполнять запросы к вашим защищенным методам api (вы можете оставить какие-то методы "без токена").

    Node.js часть
    Пример роута на логин (сделано не лучшим образом, в плане коллбэков, но что нашлось под рукой...):

    auth.js
    ...
    const v4 = require('node-uuid').v4
    const jwt = require('jsonwebtoken')
    ...
    router.post('/signin', (req, res, next) => {
    
      // валидация, например... 
    
      if (errors) {
        return res.status(400).json({ errors })
      } else {
        // поиск юзера в базе, сравнение хэша и прочие необходимые операции
        ...
       // допустим все ок, нужно ответить токеном
      // генерируем необходимые опции и сам токен
    
            const payload = {
              _id: user._id,
              iss: 'http://localhost:3000',
              permissions: 'poll',
            }
            const options = {
              expiresIn: '7d',
              jwtid: v4(),
            }
            const secret = new Buffer(process.env.AUTH0_CLIENT_SECRET, 'base64')
            jwt.sign(payload, secret, options, (err, token) => {
              // отвечаем токеном, для будущих запросов с клиента
              return res.json({ data: token })
            })
         ...
    })
    
    module.exports = router;


    Пример защищенного роута (метода, который требует токен):
    ...
    const jwt = require('jsonwebtoken')
    const Poll = require('../models/poll')
    ...
    
    const requireToken = (req,res,next) => {
      const token = req.headers['x-api-key']
      const secret = new Buffer(process.env.AUTH0_CLIENT_SECRET, 'base64')
    
      jwt.verify(token, secret, (err, decoded) => {
        if (err) {
          return res.status(401).json({ error: err.message })
        }
        req.params.userId = decoded._id
        next()
      })
    }
    ...
    
    // обратите внимание на requireToken - функция вызывается при каждом обращении к роуту
    // то есть при каждом PUT запросе по адресу (например: PUT api/v1/products/1238914)
    // будет вызываться requireToken
    
    router.put('/:id', requireToken, (req, res, next) => {
      const { productId } = req.body
      const userId = req.params.userId
    
      Poll.findById(req.params.id)
        .populate({ path: 'products' })
        .exec((err, poll) => {
            // ... необходимые действия в базе, в процессе успешного зачтения голоса...
        }
    })


    Клиентское приложение:

    Типичный ActionCreator (в качестве библиотеки для запросов можно взять bluebird, isomorphic-fetch, да хоть нативный xhr)
    actions/LoginActions.js

    export function login(data) {
      return dispatch => {
        dispatch({ type: LOGIN_REQUEST })
    
        // request в данном случае - https://github.com/KyleAMathews/superagent-bluebird-promise
        return request.post(`${API_ROOT_V1}/auth/signin`)
          .send(data)
          .then(res => {
            if (!res.ok) {
              dispatch({ type: LOGIN_FAILURE })
            } else {
              dispatch({
                type: LOGIN_SUCCESS,
                data: res.body.data,
              })
              //сохранение токена в localStorage
              localStorage.setItem('cks_token', res.body.data)
            }
          }, err => {
            dispatch({ type: LOGIN_FAILURE })
          })
      }
    }


    Пример голосования с токеном (выше, в node.js части был метод апи, а это PUT запрос с клиента)

    export function vote(productId, voteId) {
      return dispatch => {
        dispatch({ type: POLL_VOTE_REQUEST })
    
        return request.put(`${API_ROOT_V1}/api/v1/vote/${voteId}`)
          .set('X-API-Key', localStorage.getItem('cks_token')) // установка ТОКЕНА в заголовок 'X-API-Key'
          .send({ productId })
          .then(res => {
            if (!res.ok) {
              dispatch({ type: POLL_VOTE_FAILURE })
            } else {
              dispatch({
                type: POLL_VOTE_SUCCESS,
                data: normalize(res.body.data, schema.poll),
              })
            }
          }, err => {
            dispatch({ type: POLL_VOTE_FAILURE })
          })
      }
    }


    Надеюсь код формы с кнопкой "голосовать" не трубется.
    ====

    Все это можно организовать удобнее, например, выставлять токен всем запросам автоматически (речь про клиентскую часть):
    import fetch from 'isomorphic-fetch'
    ...
    const defaultHeaders = {
      Accept: 'application/json',
      'Content-Type': 'application/json',
    }
    
    function buildHeaders() {
      const authToken = localStorage.getItem('TOKEN')
      return { ...defaultHeaders, Authorization: authToken }
    }
    ...
    export function httpPost(url, data) {
      const body = JSON.stringify(data)
    
      return fetch(url, {
        method: 'post',
        headers: buildHeaders(),
        body: body,
      })
      .then(... код оработки запроса ...)
    }


    ===

    Проверить наличие токена, можно с в роутере, с помощью хука на onEnter.

    root.js
    ...
    <Provider store={store}>
          <Router history={routerHistory}>
            {configRoutes(store)} // Роуты создаются функцией, чтобы можно было использовать внутри нее store.getState()
          </Router>
        </Provider>
    ...


    routes.js
    export default function configRoutes(store) {
      function _ensureAuthenticated(nextState, replace, callback) {
        const { dispatch } = store
        const { session } = store.getState()
        const { currentUser } = session
        let nextUrl
    
        if (!currentUser && localStorage.getItem('cks.token')) {
          dispatch(getCurrentAccount())
        } else if (!localStorage.getItem('cks.token')) {
          replace('/signin')
        }
        callback()
      }
    
      return (
        <Route path='/' component={App}>
          <Route path='/signin' component={SigninContainer} />
          <Route path='/signup' component={SignupContainer} />
    
          <Route path='/locked' component={AuthenticatedContainer} onEnter={_ensureAuthenticated}>
            <Route component={LockedArea}>
              <Route path='/locked/a' component={A} />
              <Route path='/locked/b/:id' component={B} />
              <Route path='/locked/c' component={C} />
            </Route>
          </Route>
        </Route>
      )


    Остается только создать AuthenticatedContainer в котором проверять: есть ли currentUser (в рамках этого примера) и если нет - возвращать false. А если есть - this.props.children (в которых будут дальнейшие роуты..)
    ===

    Итого:
    1) у вас есть API написанное на node.js.
    2) У этого API есть защищенные методы, которые проверяют наличия токена в http-запросе. Токен выдается при запросе на логин. Само собой, операция логина (то есть POST запрос на your-api/login) не требует токена.
    3) После удачного логина, вы получаете в ответе на свой запрос токен (это уже внутри клиентского кода, и если мы говорим о redux - то внутри асинхронного вызова в actions)
    4) Сохраняете токен (например, в localStorage)
    5) Во все необходимые http-запросы устанавливаете заголовок с токеном
    Ответ написан
    15 комментариев
  • Как использовать jsx?

    maxfarseer
    @maxfarseer
    https://maxpfrontend.ru, обучаю реакту и компании
    Emmet поддерживается в JSX (sublime, например)
    Ответ написан
    4 комментария
  • Каким образом лучше всего интегрировать ReactJS с Laravel?

    maxfarseer
    @maxfarseer
    https://maxpfrontend.ru, обучаю реакту и компании
    Приложения написанные на react/angular/и т.д. ожидают на бэкэнде API.

    1. Создаете API
    2. Внутри ваших компонентов "общаетесь" с вашим API
    Ответ написан
    Комментировать
  • Как комбинировать компоненты в React?

    maxfarseer
    @maxfarseer
    https://maxpfrontend.ru, обучаю реакту и компании
    Нужно как вы написали: создавать отдельные компоненты, в которых реализован некий функционал, собственноручно или "подтянув" сторонний код.
    На выходе, будет например:
    <PhoneInput />
    <DatePicker />

    и т.д.
    Ответ написан
  • Как послать json на сервер?

    maxfarseer
    @maxfarseer
    https://maxpfrontend.ru, обучаю реакту и компании
    Вопрос не относится к реакту абсолютно. Чтобы послать данные, нужно использовать POST запрос. Из библиотек для xhr запросов, лично мне нравится isomorphic-fetch

    P.S. Вы можете хоть $.ajax (из библиотеки jquery) использовать, хоть нативный xhr...
    Ответ написан
    Комментировать