• Как устроен Webpack hot reload?

    maxfarseer
    @maxfarseer
    https://maxpfrontend.ru, обучаю реакту и компании
    https://www.youtube.com/watch?v=o0NJQYWR7BI

    И если хочется чуть больше, то в принципе вся часть 8 из скринкаста
    Ответ написан
  • Откуда идёт зависимость от user?

    maxfarseer
    @maxfarseer
    https://maxpfrontend.ru, обучаю реакту и компании
    У вас порядок передачи пропсов в компонентах выглядит так: Comment -> UserInfo -> Avatar

    Comment передает в свойстве user объект:
    {
           "url": "/",
          "name": "Nikulio"
    }


    Следовательно, этот объект теперь доступен в UserInfo через props.user. В Avatar так же передается в качестве свойства user этот же объект.

    Следовательно, у Avatar в props будет объект:
    {
        user: {
            url...
            name....
        }
    }

    Следовательно, в Avatar к значениям этих свойств можно обратиться: props.user.url , props.user.name
    Ответ написан
    2 комментария
  • Пример архитектуры большого сайта-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 или нет.
    Ответ написан
    Комментировать
  • Как в react-router сделать сайдбар опциональным?

    maxfarseer
    @maxfarseer
    https://maxpfrontend.ru, обучаю реакту и компании
    Можно сделать 2 разных "разметки", так сказать. В одной у вас есть сайдбар, в другой нет.
    2 разные разметки = 2 разных компонента (роут-с-сайдбаром, роут-без-сайдбара).
    Оборачиваете дочерние роуты в роут-с-сайдбаром, или в роут-без-сайдбара и там рисуете нужный шаблон + this.props.children. Вложенность роутов друг в друга - любая, можно таким образом еще усложнить логику отрисовки шаблона.

    p.s. 4ю версию роута еще не смотрел. Но таким решением пользуюсь с 3й версией, думаю в 4м так же, либо еще удобнее придумали.

    p.p.s. тема с фильтрацией, которую посоветовал Aves тоже подходит.

    (пример, используется getComponent - это для динамической подгрузки)
    <Route path='/reports' component={AuthenticatedContainer} onEnter={_ensureAuthenticated}>
      <Route getComponent={() => def(import('../containers/WiwthSidebar'))}>
        <Route path='/reports/a' getComponent={() => def(import('../containers/A'))} />
        <Route path='/reports/b' getComponent={() => def(import('../containers/B'))} />
      </Route>
      <Route getComponent={() => def(import('../containers/WithoutSideber'))}>
        <Route path='/reports/c' getComponent={() => def(import('../containers/C'))} />
      </Route>
    </Route>
    Ответ написан
    Комментировать
  • Что делать с огромным файлом скриптов React?

    maxfarseer
    @maxfarseer
    https://maxpfrontend.ru, обучаю реакту и компании
    Это уже файл после "разбивания на кусочки" (для гугления - code splitting) ?
    Грузите то, что нужно определенному роуту и будет получше.

    гугление не даст полной картинки сразу, но постепенно соберется.

    Потребуется использовать getComponent из React-router, а далее webpack 2 уже сам сделает почти все...

    Выглядит так:
    function def(promise) {
      return promise.then(cmp => {
        console.info('Dynamic loaded by route: ', cmp.default.displayName) // для тестирования можете логировать имя компонента
        return cmp.default
      })
    }
    
    ...
    <Route path='/signin' getComponent={() => def(import('../containers/SigninContainer'))} />
    ...
    Ответ написан
    3 комментария
  • Что нужно знать перед изучением angular и react?

    maxfarseer
    @maxfarseer
    https://maxpfrontend.ru, обучаю реакту и компании
    1) по нововведениям почитайте у Кантора
    2) далее сделайте пример из оф.доки
    3) далее по аналогии с примером из оф.доки, чуть-чуть измените что-нибудь и сделайте по-своему
    4) если речь про react, то с усложнением примера, начнется медленный переход в сторону "нужен redux/подобные ему" -> читайте доку, продолжайте накручивать пример.

    p.s. если пример вам интересен, то прогресс будет быстрее, поэтому стоит поработать с API интересных вам сайтов, steam, vk, ...
    Ответ написан
    Комментировать
  • Как сделать страницу 404, в проекте, где внутри Route есть другие Route?

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

    ReactDOM.render(
      <Router history={browserHistory}>
        <Route path="/" component={Layout}>
          <Route path="/sing" component={SignUp}/>
          <Route path="/profile" component={Profile} />
          <Route path="/register_approve" component={Validation} />
          <Route path="/forgot_password" component={ForgotPassword} />
          <Route path="/confirm_email" component={ConfirmEmail} />
          <Route path="/restore_password/:token" component={RestorePassword} />
          <Route path="/confirm_invite" component={ConfirmInvite} />
          <Route path="/my-cabinet" component={Cabinet} />
          <Route path="/members" component={Members} />
          <Route path="/invite-member" component={InviteMember} />
    
          <Route path="/not_access" component={NotAccess} />
    
          <Route path="/finance" component={Finance}>
            <Route path="/finance/project" component={FinanceProject}/>
            <Route path="/finance/fixed-costs" component={FinanceFixedCost}/>
            <Route path="/finance/fixed-costs" component={FinanceFixedCost}/>
            <Route path="/finance/salary" component={FinanceSalary}/>
            <Route path="/finance/other" component={FinanceOther}/>
          </Route>
        </Route>
        <Route path="*" component={NotFound} />
      </Router>,
      document.getElementById('root')
    Ответ написан
    2 комментария
  • Как в WebPack компилировать стили отдельно от JS?

    maxfarseer
    @maxfarseer
    https://maxpfrontend.ru, обучаю реакту и компании
    extract-text-plugin

    {
            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',
            }),
          },
    Ответ написан
    2 комментария
  • Как правильно инициализировать в проекте дефолтные настройки для одного из модулей?

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

    Либо такой вариант:
    function buildHeaders() {
      const authToken = localStorage.getItem('token')
      return { ...defaultHeaders, Authorization: authToken }
    }


    export function httpGet(url) { //экспортируете функцию для будущих вызовов
      return fetch(url, { // я использую fetch, но для axios сделать, думаю вы сможете
        headers: buildHeaders(), // те самые заголовки, которые нужны в каждом запросе
      })
      .then(checkStatus) // это уже не важно, у меня в коде просто далее идет еще несколько проверок общих
    }
    Ответ написан
    2 комментария
  • Как вывести данные с сервера без lodash?

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

    return Object.keys(this.props.posts).map(postId => {
          const currentPost = this.props.posts[postId]
          return (
            <li className="list-group-item" key={currentPost.id}>
              <span className="pull-xs-right">{currentPost.categories}</span>
              <strong>{currentPost.title}</strong>
            </li>
          );
        })
    Ответ написан
    Комментировать
  • Какой подход (библиотеки, фреймворки) используете при верстке UI?

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

    Значит при том вы ведете какую-то свою "библиотеку подобных элементов"?
    Так же и другие люди, "ведут" подобные библиотеки, еще больше других людей их используют и пишут о багах, поэтому получается обычно более "протестированный" элемент.

    Пример, для material design - https://getmdl.io/components/index.html
    Там есть github и можно посмотреть код любого компонента... а можно просто взять сразу готовый и использовать, при этом не писать самому.

    Другой пример: есть популярный bootstrap, есть у него сетка, по этой сетке делается много однотипных сайтов, дизайнеры по ней рисуют сразу изначально, в итоге у рядового "конвейрного" мастера по лендингам (ничего плохого не имею против таких специалистов) очень сильно понижается затраченное время на выполнение задачи по адаптивной верстке.
    ===

    По технологиям: вы верстаете, так наверное, используете gulp? Если нет - то пора, получите live reload (не нужно перезагружать страницу), сможете оптимизировать ваши скрипты/стили/картинки... и все это будет сильно высвобождать ваше время.
    Ответ написан
    3 комментария
  • Как реализовать грамотную проверку авторизации?

    maxfarseer
    @maxfarseer
    https://maxpfrontend.ru, обучаю реакту и компании
    Вы используете react-router? Если да, то тут все просто:
    1) роуты создаются с помощью функции, таким образом вы можете прокинуть в роутинг store
    ...
    import configRoutes from '../../routes'
    ...
    render() {
      return (
        <Provider store={store}>
          <Router history={routerHistory}>
            {configRoutes(store)}
          </Router>
        </Provider>
      )
    }


    2) Далее в роутинге, устанавливаете на "защищенные" компоненты onEnter hook:
    ...
    <Route path='/secret-area' component={SecretAreaContainer} onEnter={_ensureAuthenticated}>
    ...


    3) сама функция, смотрит есть ли в store необходимые данные:
    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('token')) {
            dispatch(getCurrentAccount())
          }
        } else if (!localStorage.getItem('token')) {
          nextUrl = location.pathname + location.search.replace('?', '&')
          replace('/signin')
        }
    
        callback()
      }
    
      // здесь ваши роуты


    Ок, по роутам готово.

    Теперь, по переадресации:
    - на success в логине, делаете редирект куда угодно:
    export function signIn(email, password) {
      return (dispatch, getState) => {
    
        dispatch({
          type: USER_SIGN_IN_REQUEST,
        })
    
        const params = {
          email,
          password,
        }
    
        httpPost(`${API_ROOT_V1}/api/authenticate`, params)
          .then((data) => {
            saveParamsToLS(data) // здесь токен можно сохранить, например
            dispatch(push('/account')) // ваш РЕДИРЕКТ, используется push из react-router-redux (что необязательно)
          })
          .catch((error) => {
            console.warn(`Sign in error: ${JSON.stringify(error)}`) //eslint-disable-line no-console
            dispatch({
              type: USER_SIGN_IN_FAILURE,
              error: error,
            })
          })
      }
    }


    и остается кейс с прямым заходом: вы должны разрулить это опять же в onEnter хуке в роутере. Так как у вас есть store, и вам доступны все данные из него, включая store.dispatch метод, добить пример не составит труда.
    Ответ написан
    3 комментария
  • Как настроить деплой с разных веток для SPA приложения?

    maxfarseer
    @maxfarseer
    https://maxpfrontend.ru, обучаю реакту и компании
    Вам нужно использовать github webhooks.
    p.s. гугл
    Ответ написан
    Комментировать
  • Как работает использование Redux вместе со state?

    maxfarseer
    @maxfarseer
    https://maxpfrontend.ru, обучаю реакту и компании
    В вашем примере, нет главного - как вы отрисовываете минуты/часы? Через state или через props? Redux не важно используете вы state или нет, реакт-компоненту - не важно используете вы redux или нет.

    Обновлять state на основе пришедших с помощью Redux props вы можете в componentWillReceiveProps
    Ответ написан
    5 комментариев
  • React router: как применять разные файлы стилей к разным страницам?

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

    Применяется он, потому что вы вынесли стили в отдельные компоненты, но они при этом грузятся у вас, наверняка, в тэг style, либо в один единственный файл и это подключается все "наверху", следовательно, хоть и стили там где необходимо подключены - они есть для всего сайта, значит будут применяться.

    Чтобы отказаться на некоторых страницах, нужно не использовать одинаковые с bootstrap имена классов на этих страницах. "Поинтереснее" решения подсказать не могу.
    Ответ написан
    Комментировать
  • Что лучше взять для сборки фронтенда webpack или gulp?

    maxfarseer
    @maxfarseer
    https://maxpfrontend.ru, обучаю реакту и компании
    Для вашей задачи - Gulp
    Ответ написан
    Комментировать
  • В каких случаях использовать PureComponent?

    maxfarseer
    @maxfarseer
    https://maxpfrontend.ru, обучаю реакту и компании
    Годная статья с хабра (плюс комментарии)
    Ответ написан
    1 комментарий
  • Redux thunk, откуда береться dispatch в экшине?

    maxfarseer
    @maxfarseer
    https://maxpfrontend.ru, обучаю реакту и компании
    Он берется из middleware redux-thunk

    Посмотрим на исходный код:

    function createThunkMiddleware(extraArgument) {
      return ({ dispatch, getState }) => next => action => {
        if (typeof action === 'function') {
          return action(dispatch, getState, extraArgument);
        }
    
        return next(action);
      };
    }


    В котором видно, что если возвращаемый тип действия - function, то вызови все тоже самое, но с аргументами (dispatch, getState и extraArgument) - которые доступны через область видимости и являются тем "что надо".

    ca799e34804e4ae7afeaffa56751700d.jpg
    Ответ написан
    4 комментария