Ответы пользователя по тегу React
  • Ошибка UglifyJs при сборке ReactJS приложения?

    Это баг, к сожалению последняя версия UglifyJs не поддерживает всякие es6. Вам либо надо транслировать в старый JS, а если вы все же этого не хотите - поставьте отдельно от вебпака плагин. У меня все работало на этой версии:
    "uglifyjs-webpack-plugin": "^0.4.3",
    Ответ написан
  • Почему props неизменяемы?

    Есть специальный метод:
    const freezedObject = Object.freeze({ a: 1, b: 5 })
    
    freezedObject.a = 'quux'; // тихо ничего не делает
    Ответ написан
    4 комментария
  • Как проектировать адаптивное spa приложение?

    Значит ли это, что адаптивная вёрстка неприменима для приложений и придётся делать различные представления на разные устройства


    Смысл адаптивной верстки в том, что содержимое подстраивается под размеры экрана. Ваш кэп :) В приведенном примере нету противоречий с принципами адаптивки

    Следовательно, обработчики тоже разные: в одном случае это переход на новый экран, в другом - открытие модального окна.


    Это можно реализовать внутри приложения. Вот пример реакта и react-router v4: https://reacttraining.com/react-router/web/example... . Там изображения в галерее открываются либо на странице, либо модальным окном. В зависимости от того, как была открыта страница (заметьте, что url у элементов галереи одинаковый при разных способах отображения)

    Или всё же можно грамотно строить адаптивные приложения?

    Да, можно. Но надо все моменты заранее продумывать

    Желательно использовать при этом динамическую загрузку модулей?

    Это позволяет оптимизировать производительность (время начального рендера, объем передаваемых данных\кода, время парсинга скриптов и так далее). Если вам это нужно - используйте)
    Ответ написан
  • Нужно ли выполнять сборку проекта для production (node/express)?

    Если API идет как полностью отдельный код и вы используете только те фичи JS, которые поддерживаются текущей версией nodejs - то ничего особо не нужно делать.. Ставите зависимости и запускаете.

    Для server-rendera скорей всего придется билдить приложение, чтобы нормально оттранслировать jsx и прочие импорты.
    Ответ написан
    4 комментария
  • Как лучше работать с массивом данных?

    Это обычный рекурсивный обход дерева. Добавление\удаление\редактирование будет зависеть от того как (и где) вы храните данные - flux\redux\whatever. В случае с редаксом - я бы хранил в state дерево в плоском виде (вам нужны будут id, но, думаю, что с монго - это не проблема).

    Отображать дерево можно так:

    const MySuperTree => (props) => (
      <ul>{props.nodes.map(node => <TreeNode {...node} />)}</ul>
    )
    
    class TreeNode extends PureComponent { 
      render() {
        const { name, val1, val2, nodes } = this.props
        return (
          <li>
            <b>{name}  | {val1} | {val1+getValFromChild(childs)} {val2}</b>
            {nodes && nodes.length > 0 && (
              <MySuperTree nodes={nodes} />
            )}
         </li>
        )
      }
    }
    Ответ написан
    6 комментариев
  • Удобная стилизация сплывающих подсказок, diegoddox/react-redux-toastr, как сделать чтобы она (подсказка) не пряталась?

    Из документации ( https://github.com/diegoddox/react-redux-toastr#to... ):
    const toastrOptions = {
      timeOut: 3000, // by setting to 0 it will prevent the auto close
      // ...
    }


    Ставим таймаут в 0 и она не будет исчезать
    Ответ написан
  • Для чего может понадобиться subsribe из store?

    Начнем с того, что redux - самостоятельное решение, которое можно использовать отдельно от стека react'а. По сему - API разрабатывается для общих нужд. В случае с connect - да, там используется subscribe.

    Если вы разрабатывается на rxjs - можно сделать observable из вашего стора (хотя сейчас для этого есть более удобный способ). Также очень полезно подписаться если вы разрабатываете инфраструктурные модули. Вот в голову пришла идея - у вас есть localStoe - вам нужно синхронизировать какой-то кусочек state, чтобы понять, что state изменился - подписываетесь на store.
    Ответ написан
    Комментировать
  • Как правильно загружать данные при серверном рендеринге + react router v4?

    Вам нужно любым удобным способом сохранить информацию о том, что данные были загружены. Это можно сделать как на уровне загрузчика
    // что-то вроде этого
    promises.push(
      store
        .dispatch(route.loadData())
        .then(() => store.dispatch(dataForRouteLoaded(req.url))
    )

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


    Либо в каждом конкретном экшене проверять есть ли требуемые данные в state перед их загрузкой.
    Ответ написан
  • Как правильно подключать reducer и action для ReactJS?

    Для начала: не совсем понятно, что вы хотите инкрементить. В добавок вы мутируете объект action... Лучше сделать как-нибудь так:
    export default function reducer(state=initialState, action) {
        switch (action.type) {
            case 'INCRE_TEST':
                return state.int + action.int
            default:
                return state
        }
    
    }


    И тут самое непонятное, как все это правильно собирать?
    Не понимаю как подключить функцию к onClick


    У вас все верно сделано, за исключением параметра функции
    const mapDispatchToProps = dispatch => {
        return {
            onClick: int => {
                dispatch(increTest(int))
            }
        }
    }


    Получается, что в качестве параметра int у вас будет event. Можно просто передавать какое-то число:
    const mapDispatchToProps = dispatch => {
        return {
            onClick: () => {
                dispatch(increTest(1))
            }
        }
    }


    А если хотите сделать именно с параметром, то передавайте его в обработчике клика:
    <button onClick={() => this.props.onClick(1)}>Click onClick</button>


    Это самый наглядный вариант, только негативно влияет на производительность, поэтому в реальных проектах не стоит так делать (нужно создать в классе Test отдельный метод, скажем, handleClick, в котором вызывать this.props.onClick(1) и уже его передавать в onClick кнопки)
    Ответ написан
    3 комментария
  • Как удалить элемент из компонента и из store?

    Да, оперируйте id. Сохраняйте его в action и дальше фильтруйте

    function removeSomething(id) {
      return { type: 'RemoveSomething_Action', payload: { id } }
    }
    
    function reducer(state = initialState, action) {
      switch(action.type) {
        //...
        case 'RemoveSomething_Action':
          return state.filter(el => el.id !== action.payload.id)
        // ...
      }
    }


    У вас так и сделано :)
    Ответ написан
    6 комментариев
  • Как проверить размеры картинки до ее отрисовки в dom?

    После того, как компонент будет добавлен в DOM - берем src из props и создаем новый DOM-элемент img, ставим обработчик onLoad и загружаем картинку. Затем проверяем размеры и устанавливаем стейт

    class Cover extends Component { 
       state = {
         loaded: false,
         width: 0,
         height: 0,
       }
    
       componentDidMount() {
         const img = document.createElement('img')
    
         img.onload = e => {
           console.log('image loaded', img.width, img.height)
           this.setState({ loaded: true, width: img.width, height: img.height })
         }
    
         img.src = this.props.src
       }
    
      renderLoading() {
        return <div>loading... </div>
      }
      
      renderLoaded() {
        const { width, height } = this.state
        const isFits = width === 140 && height === 205
        return isFits
          ? <div>обложка успешно установлена</div>
          : <div>Обложка должна быть 140х205</div>
      }
    
       render() {
           return this.state.loaded ? this.renderLoaded() : this.renderLoading()
       }
    }
    Ответ написан
    Комментировать
  • Можно ли на ReactJS динамически загружать компоненты без знания о них при сборке самого приложения (как это реализовано в Angular 2+)?

    Динамически подгружать компоненты? Это не к реакту, это к вашему сборщику.
    В последних вебпаках (2+) есть поддержка динамических импортов:

    import('moduleName').then(module => /* do something */)


    Ну и дальше вы сможете сохранить этот модуль (например в state):
    class Bundle extends Component {
      state = {
        // short for "module" but that's a keyword in js, so "mod"
        mod: null
      }
    
      componentWillMount() {
        this.load(this.props)
      }
    
      componentWillReceiveProps(nextProps) {
        if (nextProps.load !== this.props.load) {
          this.load(nextProps)
        }
      }
    
      load(props) {
        this.setState({
          mod: null
        })
        props.load((mod) => {
          this.setState({
            // handle both es imports and cjs
            mod: mod.default ? mod.default : mod
          })
        })
      }
    
      render() {
        return this.state.mod ? this.props.children(this.state.mod) : null
      }
    }
    
    export default Bundle


    А вызывать все это дело вот так:
    <Bundle load={() => import('./something')}>
      {(mod) => ()}
    </Bundle>


    Но это все в рамках проекта - добавили новый компонент - пересобрали проект. И это самая адекватная (на мой взгляд) практика. Случаи, конечно, бывают разные - но мне как-то уютнее, когда я знаю, что весь нужный код находится у меня в проекте, а не где-то там. Я имею ввиду в первую очередь зависимости ваших динамических компонентов (в первом ангуляре была своя система DI и свой подход к разработке, но с тех пор уже много воды утекло и нативные JS модули, очевидно, гораздо лучшее решение). Конечно, теоретически - можно напридумывать костылей и грузить их откуда угодно...
    Ответ написан
  • Где получить опыт в React?

    возможно есть на гитхаб какие опен сорс проекты


    Конечно же есть - их бесчисленное количество. Придумайте себе проект - и реализуйте его вот и опыт будет. По пути попробуйте актуальные библиотеки.. я бы рекомендовал изучить следующие:
    • react-router v4
    • redux, react-redux, reselect, redux-saga, redux-form
    • react-virtualized


    Есть вот такой ресурс - https://github.com/enaqx/awesome-react : там, помимо всего прочего, есть и примеры приложений на реакте.
    Ответ написан
    2 комментария
  • Redux c большим объемом данных в Store?

    Самое простое - сгенерировать 500-1000-whatever задач и посмотреть что будет с вашей системой.
    Если говорить в общем - я думаю, что это плохое решение в большинстве случаев. Тем более, если предполагаются большие объемы данных...
    • чем больше объектов, тем больше overhead на map\filter\objectAssign и операции со стейтом mapState\reselect.
    • банальный расход памяти браузера (а если с телефона?)
    • большое время загрузки и парсинга вашего json.


    А если уж большинство этих данных пользователь и вовсе не увидит - то зачем? На моей памяти такая модель применялась в интернет магазине, где было не много товаров, но это позволяло пользователям пользоваться ресурсом в offline режиме.

    PS
    Проведите тестирование (имитацию худшего сценария) и по результатам вам уже будет видно подходит это решение или нет
    Ответ написан
  • React Native. Что происходит с JavaScript прослойкой после сборки в продакшн?

    JS код остается - он запускается отдельным потоком, не блокируя основной (отрисовку UI). Ну а дальше вы общаетесь с нативными компонентами через JSX - все очень похоже на работу с DOM (ведь за исключением refs реакт инкапсулирует работу с DOM-деревом)
    Ответ написан
    Комментировать
  • Как иммутабельно удалить свойство из массива в редьюсере?

    Ниже пример решения, но насколько оно иммутабельно?


    Это идеально: filter создает новый массив.

    может быть только одна чистая функция, которая возвращается по умолчанию, или можно плодить там (естественно самое необходимое) функции


    Можно использовать хелперы (тот же lodash\ramda). Главное, чтобы в результате у вас редьюсер был чистой функцией без сайд эффектов (это значит, что все функции, которые используете внутри - также должны быть чистыми).
    Ответ написан
    Комментировать
  • Каким образом функция connect из react-redux мапит данные в пропсы?

    Провайдер передает store через контекст. Функция connect создает HOC, который подписывается на обновления store. Ну и далее вызываются ваши mapState, mapActions где вы получаете необходимые данные и мапите их в props
    Ответ написан
    2 комментария
  • React: Как отключить вставку стилей в страницу?

    Этим занимается style-loader и его можно конфигурировать - https://github.com/webpack-contrib/style-loader#url
    Ответ написан
    Комментировать
  • Как в REACT-REDUX сделать, чтобы перерендеривался только один элемент?

    Гляньте вот этот ответ React-Redux. Какой путь правильнее: вызов connect ...

    Если кратко:
    • Избавьтесь от коннектов, которые слушают большие куски стейта
    • Используйте reselect, для вычислений стейта (например, когда собираете элемент из разных редьюсеров)
    • Используйте connect элементах, которым нужны данные. Их может быть много. Список из 1000 connected-elements работает быстрее, чем список из 1000 элементов с 1м connected-element. Потому что даже PureComponent имеет свой оверхед и если дочерний компонент не обновился - это не значит, что diff алгоритм реакта не будет обрабатывать изменения в родительском компоненте
    Ответ написан
    2 комментария
  • Как реализовать динамический import для code splitting в Webpack 2?

    UPD2: Решение проблемы
    У вас есть название entryPoint и именно его нужно указать как name при конфигурации commonChunksPlugin
    entry: {
        application:  /* ... */
      },
    ....
    plugins: {
      new webpack.optimize.CommonsChunkPlugin({
          name: 'application', // <--- Так же как и entryPoint
          async: "vendors", // <--- будет использовано как имя файла (можно оставить просто true). "vendors.js"
          children: true,
          minChunks: 2 // <--- должно быть >= 2
        })
    }


    Похоже, что это issue. Обсуждение идет тут -https://github.com/webpack/webpack/issues/5109#iss...

    OLD:
    старый ответ
    По-идее у вас должно быть что-то такое:

    {
      entry: {
        main: './reactStartup.js'
      },
      output: {
        filename: '[name]-bundle.js',
        chunkFilename: '[name]-chunk.js',
        path: path.resolve(__dirname, 'dist'),
        publicPath: 'dist/'
      },
      plugins: [
        new webpack.optimize.CommonsChunkPlugin({
          async: true,
          children: true,
          minChunks: 2,
        }),
      ]
    }


    Обратите внимание на minChunks по-умолчанию там скорей всего Inf (документация), а это значит, что в этот чанк ничего не попадает.

    Но CommonsChunkPlugin просто выделяет общие модули (которые используются >= 2х раз), а для динамических импортов вам нужен отдельно плагин для babelrc:
    // .babelrc
    {
      "plugins": [
        "syntax-dynamic-import"
      ]
    }


    UPD1
    Еще дело может быть в модулях - я с вебпаком2 давно отключил преобразование модулей в babel ( "modules": false):
    "presets": [
        [
          "env",
          {
            "targets": {
              "node": "current",
              "browsers": "last 2 versions"
            },
            "modules": false,
            "loose": true
          }
        ],
        "react",
      ],
    Ответ написан