• Как правильно перечислить класс в шаблоне?

    rockon404
    @rockon404 Куратор тега React
    Frontend Developer
    Это, пожалуй, наихудший путь которым только можно пойти.
    Реализация компонента по-хорошему должна быть инкапсулирована, а вы должны работать с его интерфейсом.
    <Button
      type="outline"
      size="sm"
      color="succes"
      disabled={isButtonDisabled}
      onClick={handleClick}
    >
      Succes
    </Button>
    Ответ написан
    Комментировать
  • Как организовать для работы список файлов и папок с уровнем вложенность в обьекте?

    rockon404
    @rockon404 Куратор тега React
    Frontend Developer
    Что-то вроде:
    [
      {
        name: 'some_name',
        type: 'folder',
        isHidden: false,
        size: 23123,
        created_at: 4342323434,
        edited_at: 3453123434,
        path: '/some_place/some_name',
        children: [],
        childrenLength: 4,
        access_rights: [],
      },
      {
        name: 'some_image.png',
        type: 'file',
        isHidden: false,
        size: 23123,
        created_at: 4342323434,
        edited_at: 3453123434,
        path: '/some_place/some_image.png',
        access_rights: [],
      },
    ]
    Ответ написан
    Комментировать
  • Как правильно использовать mapStateToProps с асинхронным поведением компонента?

    rockon404
    @rockon404 Куратор тега React
    Frontend Developer
    Не надо обрабатывать подобные вещи в mapStateToProps. Оставьте просто:
    const mapStateToProps = (state, ownProps) => ({
      coin: coinSelector(state, ownProps),
      isLoading: isCoinsLoadingSelector(state),
    });

    В методе render:
    render() {
      const { coin, isLoading } = this.props;
    
      if (isLoading) return <Preloader />;
    
      if (!isLoading && !coin) return <NotFound />;
    
      return <CoinDetails coin={coin} />;
    }

    Учитесь проектировать хранилище, задавать начальное состояние и писать render метод так, чтобы он успешно выполнялся вне зависимости от того получили вы необходимые данные или нет.
    Ответ написан
    4 комментария
  • Возможно ли получить элемент массива из состояния redux, используя mapStateToProps?

    rockon404
    @rockon404 Куратор тега React
    Frontend Developer
    const coinSelector = (state, ownProps) =>
      state.coins.data.find(coin => coin.symbol === ownProps.match.params.id);
    
    const mapStateToProps = (state, ownProps) => ({
      coin: coinSelector(state, ownProps),
    });
    Ответ написан
    Комментировать
  • Нужно ли изучать шаблонизаторы, если планирую использовать ReactJS?

    rockon404
    @rockon404 Куратор тега React
    Frontend Developer
    На то, чтобы вкатиться в тему уйдет час-три. Знания полезные. Достаточно просто попробовать базовые вещи. Зазубривать API шаблонизатора, которым не факт, что будете когда-нибудь пользоваться, не стоит.
    Ответ написан
    Комментировать
  • Disable кнопки после обновления redux store?

    rockon404
    @rockon404 Куратор тега React
    Frontend Developer
    Очевидно, что так:
    render() {
        return (
          <SubList d={visibility}>
            {list.map((item, i) => (
              <Button
                key={i.toString()}
                onClick={this.handleClick}
                disabled={item.isLoading}
              />
            ))}
          </SubList>
        );
      }
    Ответ написан
  • Оценка своего уровня. Как улучшить код?

    rockon404
    @rockon404 Куратор тега React
    Frontend Developer
    1. Используйте const вместо let для определения переменных которые не переопределяются в коде. Это помогает снизить когнитивную нагрузку с человека читающего код и негласный стандарт в React разработке.

    2. Такие вещи как globalStyles и конфигурацию store лучше вынести в отдельные файлы. Они могут со временем хорошо разрастись.
    По поводу globalStyles, вы вообще можете вынести их в отдельный css файл.

    3. Вместо:
    {
      isModal
      ? <Route path="/auth" component={AuthPopup} />
      : null
    }

    лучше:
    {isModal && <Route path="/auth" component={AuthPopup} />}


    4. Вместо:
    function mapDispatchToProps(dispatch) {
        return {
            autoLogin: () => dispatch(autoLogin()),
            getBrowser: () => dispatch(getBrowser()),
            getMedia: () => dispatch(getMedia())
        }
    }


    лучше:
    const mapDispatchToProps = {
      autoLogin,
      getBrowser,
      getMedia,
    };


    5. Точки с запятыми в конце то есть, то нет. Определитесь и приведите код к одному виду.

    6.
    & label {}
    & input {}
    & span {}

    Это не очень хороший подход. Во-первых ваши стили не изолированные, что может приводить к неожиданным результатам. Во-вторых у вас очень много дублирования стилей. Определите Input и Label как базовые компоненты и используйте в разных местах, то же с остальным если есть.

    7. Почему папка со страницами называется Containers? Дань бойлерплейтам?

    8. Использование trailing comma является хорошей практикой.

    9.
    import {combineReducers} from 'redux';
    import photoReducer from './photoReducer';
    import authReducer from './authReducer';
    import globalReducer from './globalReducer';
    
    export default combineReducers({
        photoReducer, authReducer, globalReducer
    })


    Все таки приятней работать с хранилищем в котором ключи не имеют в названии слова reducer:
    import {combineReducers} from 'redux';
    import photo from './photoReducer';
    import auth from './authReducer';
    import global from './globalReducer';
    
    export default combineReducers({
      photo, 
      auth,
      global,
    });


    10. Забудьте вообще, что в языке есть возможность использовать вложенный тернарный оператор:
    return e === 'invalid-email' ? 'Неверно указан e-mail'
        : e === 'user-not-found' ? 'Указанный e-mail на найден'
        : e === 'wrong-password' ? 'Неверный пароль'
        : e === 'email-already-in-use' ? 'Указанный e-mail уже используется'
        : e === 'network-request-failed' ? 'Нет подключения к интернету'
        : e === 'operation-not-allowed' ? 'Произошла ошибка, попробуйте снова'
        : e === 'popup-closed-by-user' ? 'Окно авторизации закрыто пользователем'
        : e === 'account-exists-with-different-credential' ? 'Аккаунт уже существует с другими данными, используйте другой способ авторизации'
        : e

    Это одна из самых худших практик в JavaScript разработке. Тут лучше подойдет конструкция switch case

    11. Константы actionTypes лучше вынести в папку constants и разложить по разным файлам, иначе со временем у вас там будет свалка.

    12. Вместо:
    import {SET_ACTIVE, CHANGE_VALUE, SET_DEFAULT, UPLOAD, UPDATE_IMAGE, SET_IMAGE_ERROR, SET_LIKE, SET_COMMENT, ADD_ARTICLE_SUCCESS, FETCH_ARTICLES_START, FETCH_ARTICLES_SUCCESS, FETCH_ARTICLES_ERROR} from '../actions/actionTypes';

    Лучше:
    import {
      SET_ACTIVE,
      CHANGE_VALUE,
      SET_DEFAULT, UPLOAD,  
      UPDATE_IMAGE,
      SET_IMAGE_ERROR,
      SET_LIKE,
      SET_COMMENT,
      ADD_ARTICLE_SUCCESS,
      FETCH_ARTICLES_START,
      FETCH_ARTICLES_SUCCESS,
      FETCH_ARTICLES_ERROR,
    } from '../actions/actionTypes';


    13. Попробуйте внедрить библиотеку reselect. И для получения значения из store вместо записи вида:
    function mapStateToProps(state) {
        return {
            browser: state.globalReducer.browser
        }
    }


    использовать селектор:
    const mapStateToProps = state => ({
      browser: browserSelector(state),
    });
    Ответ написан
    12 комментариев
  • Ререндер - это нормально?

    rockon404
    @rockon404 Куратор тега React
    Frontend Developer
    Перерисовка срабатывает только потому, что срабатывает перерисовка родительского компонента. Если родитель React.Component, то его перерисовки можно контролировать с помощью метода shouldComponentUpdate.
    Ответ написан
    Комментировать
  • Как вызвать функцию вложенного компонента React?

    rockon404
    @rockon404 Куратор тега React
    Frontend Developer
    1. У вас код невалидный. Ключевые слова class и for зарезервированны языком.
    Используйте вместо className и htmlFor.
    2. this.state ={url:url} Так state обновлять нельзя.
    3. Создаете FormDatra но не используете.

    После исправления этих пунктов, если не заведется смотрите ошибки в консоли, смотрите вкладку network, можно и сам метод подебажить тем же выводом console.log.
    Ответ написан
  • Как сделать сложный routing в react?

    rockon404
    @rockon404 Куратор тега React
    Frontend Developer
    Как вариант решения, написать компонент-контейнер MainLayout:
    const MainLayout = ({ children }) => (
      <Wrapper>
        <Header />
        <Content>
          {children}
        </Content>
        <Footer />
      </Wrapper>
    );

    В компоненте App:
    <Switch>
      <Route exact path="/" component={Main} />
      {/* остальные роуты */}
    </Switch>

    В pages/Main и остальные страницы с хедером и футером:
    const Main = () => (
      <MainLayout>
        {/* тут содержимое страницы */}
      </MainLayout>
    );
    Ответ написан
    Комментировать
  • Мобильная верстка React?

    rockon404
    @rockon404 Куратор тега React
    Frontend Developer
    Определять UА и рисовать мобильные версии компонентов. Там, где хватит мобильных стилей css, использовать медиазаросы или рендерить стили по тому же UA.
    Ответ написан
  • React и бэкэнд. Как отобразить пользователей с их правами и представить ситуативный набор кнопок?

    rockon404
    @rockon404 Куратор тега React
    Frontend Developer
    Вам хватит простых условий:
    render() {
      const { me, project, users } = this.props;
      const isMeModerator = isModerator(me);
      const isMeCreator = me.id === project.creator_id;
      const shouldShowSearchForm = isMeModerator || isMeCreator;
    
      return (
        <div>
          {shouldShowSearchForm && <Search />}
          <ul>
             {users.map(user => {
               const isUserCreator = user.id === project.creator_id;
               const shouldShowDeleteButton = (isMeModerator || isMeCreator) && !isUserCreator;
    
               return (
                 <li key={user.id}>
                   {user.name}
                   {shouldShowDeleteButton && <Button>Delete</Delete>}
                   {isUserCreator && <CreatorLabel />}
                 </li>
               );  
             }}
          </ul>
        </div>
      );
    }


    Если в приложении много элементов которые зависят от ролей и полномочий можно написать контейнер с интерфейсом вида:
    <PermissionsChecker requiredPermissions={permissions}>
      <SomeComponent />
    </PermissionsChecker>

    Тут permissions можно коннектить в PermissionsСhecker из стора и сверять с полученными в свойстве requiredPermissions и в случае наличия необходимых прав в store, возвращать дочерний компонент, в противном случае null.
    Ответ написан
    5 комментариев
  • Как это переписать на es6?

    rockon404
    @rockon404
    Frontend Developer
    Насколько я понимаю вы хотите обновить состояние редьюсера. Делать это надо иммутабельно:
    const { model, rows } = payload;
    
    return { ...state, model, rows };

    или:
    return {
      ...state,
      model: payload.model,
      rows: payload.rows,
    };
    Ответ написан
    2 комментария
  • Как правильно использовать this.props.children?

    rockon404
    @rockon404 Куратор тега React
    Frontend Developer
    Как правильно использовать this.props.children?


    import React from 'react';
    import ReactDOM from 'react-dom';
    
    const SomeComponent = ({ name }) => (
      <span>{name}</span>
    );
    
    const SomeContainer = ({ children }) => (
      <div>{children}</div>
    );
    
    const Example = () => (
      <SomeContainer>
        <SomeComponent name="John" />
      </SomeContainer>
    );
    
    ReactDOM.render(
      <Example />,
      document.getElementById('root');
    );


    Результат:
    <div id="root">
      <div>
        <span>John</span>
      </div>
    </div>
    Ответ написан
    9 комментариев
  • Почему такой результат?

    rockon404
    @rockon404
    Frontend Developer
    В выражении:
    var a = [1][1];
    Вы присваиваете a элемент массива [1] с индексом 1. Так как такого элемента в массиве нет, а получает значение undefined.

    Так как undefined не кастуется ни в true, ни в false, ни одно из условий не истинно и в консоль ничего не выводится.
    Ответ написан
    Комментировать
  • Как присвоить className="active" для li?

    rockon404
    @rockon404 Куратор тега React
    Frontend Developer
    import { Link, withRouter } from 'react-router-dom';
    
    const Example = ({ location }) => (
      <ul>
        <li className={location.pathname === '/' ? 'active' : ''}>
          <Link to="/">
            <u>Главная</u>
          </Link>
        </li>
        <li className={location.pathname === '/about' ? 'active' : ''}>
          <Link to="/about">
            <u>О нас</u>
          </Link>
        </li>
      </ul>
    );
    
    export default withRouter(Example);


    Демо.
    Ответ написан
    Комментировать
  • Как правильно локализировать react приложение используя react-router 4 и react-intl?

    rockon404
    @rockon404 Куратор тега React
    Frontend Developer
    Можно попробовать как-то так:

    App:
    <Switch>
      <Route path="/(en|ru|de|es|it|jp)" component={Routes} />
      <Redirect to={`/${currentLocale.code}${location.pathname}`} />
    </Switch>


    Routes:
    <Switch>
      <Route exact path={match.path} component={Main} />
      <Route path={`${match.path}/other`} component={Other} />
      <Redirect to={match.url} />
    </Switch>
    Ответ написан
  • TypeScript с React + Redux?

    rockon404
    @rockon404 Куратор тега React
    Frontend Developer
    Знаете ли вы статьи и т.д где показано, как на самом деле нужно писать React c TypeScript'ом ?

    Есть две разные технологии. Есть опыт из совместного использования. В статьях которые вы прочитали, а так же в докладах и открытых репозиториях люди делятся своим опытом. О том "как на самом деле нужно" разные люди тут вам скажут немного разное.

    Официальные ссылки:
    TypeScript: React & Webpack
    TypeScript-React-Starter
    Ответ написан
  • Проекты для разбора новичку, для обучения, есть годные?

    rockon404
    @rockon404 Куратор тега React
    Frontend Developer
    Открываем github в поиске вводим:
    1. React redux real world
    2. React redux weather app
    3. React redux reddit/twitter/youtube/etc client
    4. React redux dashboard
    5. React redux starter. Бойлерплейты тоже очень полезно изучать. Скачиваем. Открываем package.json изучаем каждый пакет в зависимостях. Отвечаем на вопросы: Что это? Зачем оно тут? Как используется? Необходимо ли оно вам? Если не, то выпиливаем без следа.

    По всем пунктам смотрим именно те проекты, у которых есть какое-никакое количество звезд и форков.

    Читаем все свежие статьи по теме.

    React Redux links
    Ответ написан
    1 комментарий