• Как сделать анимацию добавления элемента?

    maxfarseer
    @maxfarseer
    https://maxpfrontend.ru, обучаю реакту и компании
    Есть анимация в реакте ( React transition group ), которая сделана на основе ng-animate, которая в свою очередь использовалась в ангуляре. Если с ней знакомы, то быстро въедете, если нет - придется, наверное, пару раз перечитать доку.

    Суть: вы добавляете css классы по типу NAME-enter, NAME-enter-active и подобное (все опять же есть по ссылке выше), а в реакт компоненте указываете внутри ReactCSSTransitionGroup transitionName="NAME"
    Ответ написан
    Комментировать
  • Как открыть страницу поста в wordpress rest api?

    maxfarseer
    @maxfarseer
    https://maxpfrontend.ru, обучаю реакту и компании
    Судя по документации, чтобы получить пост, вам нужно вызвать:
    GET /wp/v2/posts/<id>
    Собственно в чем проблема?

    как сделать вывод именно того поста по которому нажали

    Передать именно тот id в запрос. Если вопрос в этом - то id можно взять, например из data-* атрибута, предварительно туда запихнув его в момент рендера всех постов на странице.

    Если вопрос в том, как открыть его по отдельному роуту, то вам нужен react-router и роут вида:
    <Route path='/posts/:id' component={PostMoreContainer} />


    Тогда у вас в this.props.params будет id вашей статьи и вы сможете выполнить GET запрос в момень componenDidMount. Подробнее в документации реакт-роутера.

    p.s. недавно подъехала статейка (ENG) по вашему вопросу.
    Ответ написан
    1 комментарий
  • Как перерисовывается DOM при использовании с Redux?

    maxfarseer
    @maxfarseer
    https://maxpfrontend.ru, обучаю реакту и компании
    В общем случае, метод render компонента вызывается в случае изменения state / props
    Никто (даже создатель библиотеки Redux) не просит вас отказываться от state. Это хорошая и удобная "фича" компонентов в react.

    Когда вы подключаете redux, вы оборачиваете все свое приложение в Provider (конечно, с указанием store). Затем Provider прокидывает куда нужно (в зависимости от ваших "подключенных" через функцию connect компонентов) необходимые props. Так как приходят новые props - вызывается метод render и компонент перерисовывается.

    Во всем этом можно убедиться, если посмотреть ваше корректное приложение на redux через React Dev Tools в консоли браузера. Вы увидите, что на самом верху "гнездится" Provider с кучей данных. Затем ниже по дереву, вы найдете свои, обернтуые в connect(Компонент) компоненты. Никакой магии здесь нет.
    Ответ написан
    Комментировать
  • React.js: Почему может не рендериться компонент?

    maxfarseer
    @maxfarseer
    https://maxpfrontend.ru, обучаю реакту и компании
    Так же (плюс то, что вам уже ответели), возможно, что в компоненте ./Message.jsx неправильный export default

    Если там указн export без default, то значит нужно импортировать с фигурными скобками, причем имя в импорте, должно совпадать с именем в экспорте. (например, import { Message } from ... )

    p.s. приложите код компонента Message
    Ответ написан
    Комментировать
  • Какая разница в инструментах webpack?

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

    webpack-dev-middleware - собственно, middleware, который добавляет возможности вашему другому серверу (в случае тэга вопросов - написанному на node.js и фреймворке express). Что добавляет? Ну хотя бы, возможность hot-reload'a..

    Что и где использовать разницы нет. Как вам удобнее так и делайте. Либо просто webpack-dev-server, либо какой-то ваш "усложенный" сервер написанный на node.js + middleware webpack-dev-server. Под middlewar'ом можно понимать некий "усилитель", как уже было написано, например: усиливай мой "сервер" на "hot-reload"
    Ответ написан
    Комментировать
  • Почему не обновляется props после unshift и dispatch?

    maxfarseer
    @maxfarseer
    https://maxpfrontend.ru, обучаю реакту и компании
    Взял текущее состояние, добавил в начало массива элемент. сделал диспатч нового массива.

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

    Т.е. вы возвращаете тот же самый объект (в js объекты передаются по ссылке), для react вьюхи ничего не изменилось, значит render вызывать не надо => ничего не происходит.

    Попробуйте возвращать новый(!) массив, в вашем случае это:
    setAdminData: [clients_info, ...currentList]

    Либо чуточку понятнее, но вставляя в конец массива:
    setAdminData: currentList.concat(clients_info)

    Метод concat всегда возвращает новый массив.

    Ну и чтобы стало совсем понятно в чем дело, попробуйте в консоли выполнить следующий код:
    let arr1 = [1,2,3,4]
    let arr2 = arr1
    arr2.unshift(1)
    console.log(arr1)

    Вопросы: чему равен arr1? Почему? Будет ли arr1 === arr2, почему?
    Еще вопросы: В каком случае react вызывает функцию render?
    Ответ написан
    5 комментариев
  • Как правильно настроить webpack-dev-server?

    maxfarseer
    @maxfarseer
    https://maxpfrontend.ru, обучаю реакту и компании
    1) либо не создан index.html на одном уровне с конфигом webpack
    2) либо нет роута по '/'

    p.s. + покажите console браузера, может там еще какая ошибка по делу будет.
    Ответ написан
  • Как подружить React, OpenSeaDragon и плагин селекта к нему?

    maxfarseer
    @maxfarseer
    https://maxpfrontend.ru, обучаю реакту и компании
    Судя по доке, вам достаточно "Include dist/openseadragonselection.js after OpenSeadragon in your html." (добавить openseadragonselection после вашего OpenSeadragon скрипта). Вы вроде бы так и сделали..

    Думаю, стоит попробовать без npm просто в index.html подключить сначала OpenSeadragon, затем OpenSeadragonSelection (с помощью тэга scripts) и далее уже создавать viewer как вы это делаете в вопросе. Если так будет работать, то уже думать дальше, либо так и оставить. Если так работать не будет, то вопрос не в том, как подружить React + OpenSeaDragon + плагин, и стоит создать чистый index.html статичный и прямо в нем прописать в тэге scripts пример из документаций, чтобы убедиться, что все на самом деле работает.
    Ответ написан
  • Примеры приложений, разработанных на React/Angular?

    maxfarseer
    @maxfarseer
    https://maxpfrontend.ru, обучаю реакту и компании
    На react: facebook, instagram.. или здесь целый список.

    Здесь можно подсмотреть некоторые open source проекты на реакте.
    Ответ написан
    Комментировать
  • Как в webpack задать компиляцию в несколько файлов?

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

    для webpack 2:
    module.exports = {
      devtool: 'cheap-module-source-map',
      entry: [
        './src/index'
      ],
      output: {
        path: path.join(__dirname, 'production/public/'),
        filename: 'bundle.js',
        publicPath: '/',
      },
      plugins: [
        new webpack.DefinePlugin({
          'process.env': {
            'NODE_ENV': JSON.stringify('production')
          }
        }),
        new ExtractTextPlugin({
          filename: 'style.css',
          disable: false,
          allChunks: false, // true
        })
      ],
      module: {
        rules: [
          {
            test: /\.js$/,
            loaders: ['babel-loader'],
            include: path.join(__dirname, 'src'),
          },
          {
            test: /\.css$/,
            loader: ExtractTextPlugin.extract({
              fallbackLoader: 'style-loader',
              loader: ['css-loader', 'postcss-loader'],
              publicPath: '/public',
            }),
          }, {
            test: /\.scss$/,
            loader: ExtractTextPlugin.extract({
              fallbackLoader: 'style-loader',
              loader: ['css-loader', 'postcss-loader', 'sass-loader'],
              publicPath: '/public',
            }),
          },
    ....


    Для webpack 1:
    module.exports = {
      devtool: 'cheap-module-source-map',
      entry: [
        './src/index'
      ],
      output: {
        path: path.join(__dirname, 'production/public/'),
        filename: 'bundle.js',
        publicPath: '/',
      },
      plugins: [
        new webpack.DefinePlugin({
          'process.env': {
            'NODE_ENV': JSON.stringify('production')
          }
        }),
        new ExtractTextPlugin('style.css', {
          allChunks: false
        })
      ],
      module: {
        loaders: [
          {
            test: /\.js$/,
            loaders: ['babel'],
            include: path.join(__dirname, 'src')
          },
          {
            test: /\.scss$/,
            include: path.join(__dirname, 'src'),
            loader: ExtractTextPlugin.extract('style-loader', 'css-loader!postcss-loader!sass-loader')
          },
          {
            test: /\.css$/,
            loader: ExtractTextPlugin.extract('style-loader', 'css-loader')
          },
    ...


    Само собой, нужно не забыть добавить ExtractTextPlugin
    const ExtractTextPlugin = require('extract-text-webpack-plugin');
    Ответ написан
    5 комментариев
  • React. Как динамически вешать обработчики?

    maxfarseer
    @maxfarseer
    https://maxpfrontend.ru, обучаю реакту и компании
    Добавлю, что если есть необходимость навешивать обработчики на события, которых нет "из коробки" (react events), например на resize окна,, можно использовать:
    1) addEventListener (+ создание событий)
    2) привычное вам jquery (многие против этого, лично мое мнение: иногда необходимость есть, ничего плохого здесь не вижу)

    p.s. для доступа к DOM элементу, можете использовать ref.
    Ответ написан
    Комментировать
  • Как правильно реализовать сортировку и сортинг в redux для больших объёмов данных?

    maxfarseer
    @maxfarseer
    https://maxpfrontend.ru, обучаю реакту и компании
    Поддерживаю, Mikhail Osher по поводу normalizr. По этому поводу хорошо объясняется (на англ) в этом курсе: Building React Applications with Idiomatic Redux.
    Ссылка на урок про normalizr внутри этого курса.
    Ответ написан
    Комментировать
  • Есть ли смысл изучать Reac, Angular без хорошего знания JS?

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

    Но на практике бывает иначе. Поэтому, если можете пройти туториал на любом из сайтов (реакта/ангуляра) - пытайтесь сделать что-то посложнее. Рано или поздно понимание того, что азы нужно подтягивать придет, но при этом уже будет сколько-то монет в кармане + не потеряется мотивация программировать.

    P.S. да, это вредный совет.
    Ответ написан
    Комментировать
  • Как вывести данные API в таблицу?

    maxfarseer
    @maxfarseer
    https://maxpfrontend.ru, обучаю реакту и компании
    Не надо с DOM напрямую работать.
    Создаете в state переменную: data
    Далее в componentDidMount выполняете ajax запрос и его результат записываете через this.setState({data ... })
    В render методе своего компонента, в таблице делаете обход по this.state.data с помощью map / forEach / тд

    Пример:

    ...
    constructor(props) {
        super(props)
        this.state = {
          data: []
        }
    }
    ...
    componentDidMount() {
        // ваш ajax запрос
        // в success коллбэке устанавливаете новый state, из-за этого произойдет ре-рендер
        success: function(data) { this.setState(data) }
    }
    render() {
    const { data } = this.state
    ...
        <table className='table table-bordered table-striped'>
            <thead>
              <tr>
                <th>name</th>
              </tr>
            </thead>
            <tbody>
              {
                data.map(item => {
                  return (
                    <tr key={item._id}>
                      <td>{item.name}</td>
                    </tr>
                  )
                })
              }
            </tbody>
          </table>
    ...
    }
    Ответ написан
    Комментировать
  • Не стартует проект из npm start, в чем проблема?

    maxfarseer
    @maxfarseer
    https://maxpfrontend.ru, обучаю реакту и компании
    npm install bower -g на отлично прошел

    Это вы установили bower глобально.

    Для запуска шаблона, вам наверняка нужно:
    1) npm install
    2) bower install
    3) далее, то что написано в доке, может быть gulp build, например.
    Ответ написан
    3 комментария
  • Чем отличается forceUpdate от setState?

    maxfarseer
    @maxfarseer
    https://maxpfrontend.ru, обучаю реакту и компании
    Дополню Иван на тот случай, если у вас трудности с переводом:
    forceUpdate стоит вызывать если render вашего компонента зависит от чего-то еще (кроме props/state).

    Главный побочный эффект - лишние перерисовки. Второе: forceUpdate на текущем компоненте проигнорирует shouldComponentUpdate...

    В общем, как вам уже ответили, плюс все тот же перевод документации: старайтесь избегать forceUpdate

    p.s. мне на практике ни разу еще не приходилось использовать.
    Ответ написан
    4 комментария
  • Общая библиотека для юнит тестирования React Redux GQL?

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

    Банальный тест. Проверяем, что устанавливается isFetching в true в момент запроса.
    // кусочек из reducer'a
      case GET_DETAILED_FILES_REQUEST:
          return {
            ...state,
            isFetching: true,
          }
    ...
    
      // код из теста
      it('GET_DETAILED_FILES_REQUEST', () => {
    
          const action = {
            type: GET_DETAILED_FILES_REQUEST,
          }
    
          const nextState = reducer(initialState, action) // где reducer = ваш настоящий редьюсер, например " import reducer from '../../src/reducers/detailedFiles' "
    
          expect(nextState).to.deep.equal({
            ...initialState,
            isFetching: true,
          })
        })


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

    maxfarseer
    @maxfarseer
    https://maxpfrontend.ru, обучаю реакту и компании
    Первый вариант не плох, его используют, например: datepicker, react-select библиотеки.

    React-virtualized, например, позволяет подключить стили с помощью: import 'react-virtualized/styles.css' (и при этом не нужно писать путь от node_modules), думаю если разобраться как они это сделали - для вас это будет решением)
    Ответ написан
    Комментировать
  • Где хранить текущее значение формы?

    maxfarseer
    @maxfarseer
    https://maxpfrontend.ru, обучаю реакту и компании
    я храню меняющуюся информацию в state именно этого компонента

    Это логично, для этого (изменяемых свойств компонента) и был придуман state.

    стоит ли эти текущие state объявить в state всего приложения и менять их там

    Я так понимаю, под state всего приложения понимается либо redux store, либо state какого-то родительского компонента. Если второе - однозначно нет, так как при изменении - будет перерисовываться всё приложение (все потомки), если же речь идет про redux store, то какие-то данные, которые необходимы вам в других местах (кроме текущего компонента) стоит класть туда, но при этом иметь ввиду, что все компоненты, которые "подписаны на эти данные" (с помощью функции connect) будут перерисовываться при изменении.

    p.s. отвечая на вопрос "где хранить текущее значение формы?" - я бы хранил в state компонента, так как обычно оно больше нигде в других компонентах не нужно.
    Ответ написан
    3 комментария
  • Как получить идентификатор элемента(переменную i)?

    maxfarseer
    @maxfarseer
    https://maxpfrontend.ru, обучаю реакту и компании
    Я бы сделал с помощью data-* атрибута, но в этом ответе возникла дискуссия, так что выбирайте что больше понравится.
    ..
    deleteNote(e) {
      console.log(e.target.dataset.item) //здесь будет идентификатор элемента
    }
    ...
    <span onClick={self.deleteNote} data-item={i} className={"close"}>X</span>
    ...
    Ответ написан
    Комментировать