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

    rockon404
    @rockon404 Куратор тега React
    Frontend Developer
    1. map - метод для преобразования данных, а не для перебора.
    2. Если изменяемые только два свойства, то не ясно зачем вам вообще иметь сложную вложенную структуру и держать ее в state.
    Ответ написан
    Комментировать
  • Понимание жизненного цикла React вкупе с получением данных от сервера?

    rockon404
    @rockon404 Куратор тега React
    Frontend Developer
    В данном примере curPrice - это props получаемые от сервера

    Метод жизненного цикла componentDidMount вызывается после render.
    Ничего удивительного в том, что при первой отрисовке вместо данных вы получаете undefined нет. К этому моменту еще даже не инициирован ваш запрос на сервер.

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

    Тут не ясно для чего вам вообще использовать состояние. Если вы никак не изменяете это значение в своем компоненте, то используйте его напрямую из props.
    Ответ написан
  • Как правильно вставить тэги, не нарушив структуру html?

    rockon404
    @rockon404 Куратор тега React
    Frontend Developer
    Как вариант, анализировать строку на парные теги и перед открывающими тегами без пары закрывать span и открывать сразу после.

    Например, исходная строка:
    %%START<strong>Lorem ipsum</strong> <i>dolor <u>sit amet%%END

    обработанная:
    <span><strong>Lorem ipsum</strong> </span><i><span>dolor </span><u><span>sit amet</span>

    В итоге, три тега span покрывают весь необходимый текст не нарушая структуру документа.
    Ответ написан
    Комментировать
  • Как совместить React JS + D3?

    rockon404
    @rockon404 Куратор тега React
    Frontend Developer
    Возможно, вам подойдет готовое решение вроде recharts и подобных библиотек.
    Ответ написан
    Комментировать
  • Как избежать использования чрезмерного использования useMemo?

    rockon404
    @rockon404 Куратор тега React
    Frontend Developer
    useMemo использует поверхностное сравнение зависимостей, так же, каждый render определяется функция колбек, если она прописана в теле компонента.

    Та же фильтрация данных или рендер списков, обычно стоят дороже. Вы можете посмотреть исходный код хуков и оценить все внутренние вызовы, которые делает библиотека.

    Следует помнить, что в документации есть примечание, что React может забыть ваше значение, поэтому использовать этот хук следует только для меморизации.

    Видел примеры кода, когда useMemo использовали и для создания контекста и для обновления состояния. Так делать не следует, так как может произойти потеря созданного таким способом контекста или сброс состояния.
    Ответ написан
    Комментировать
  • Чем реализация Virtual DOM отличается от createDocumentFragment (), если состояние не наблюдается?

    rockon404
    @rockon404 Куратор тега React
    Frontend Developer
    Virtual DOM React не имеет никакого отношения к DocumentFragment. Отсюда назревает ответ на ваш вопрос, что реализация отличается всем.

    Он использует эффективные алгоритмы сравнения для обновления изменений вперед и назад и других случаев использования.

    Virtual DOM это лишь упрошенная модель DOM-древа, никаких алгоритмов Virtual DOM не использует, это делает ReactDOM при сверке древа. Никаких вставок Virtual DOM в реальный DOM не происходит. Хотя бы по причине полной несовместимости.

    Если вам действительно интересно как происходит работа с Virtual DOM и сверка в React, то можете прочитать одну из многочисленных статей на эту тему.
    Ответ написан
    Комментировать
  • Что делать, если в componentDidMount мне надо зарендерить react-элемент в dom?

    rockon404
    @rockon404 Куратор тега React
    Frontend Developer
    JSX код компонента и HTML-элементы это совершенно разные вещи. Так делать нельзя.

    Ваша задача, по-хорошему, решается одним css правилом:
    .my-svg-selector:hover {
      fill: red;
    }
    Ответ написан
  • Как правильно обновить state компонента?

    rockon404
    @rockon404 Куратор тега React
    Frontend Developer
    О преимуществах и недостатках использования иммутабельного обновления данных написан не один десяток статей. Библиотека React использует эту концепцию для отслеживания изменений состояния и свойств компонентов.

    И зачем при выполнении setState() делать копию массива users, если в новый массив все равно копируются только ссылки на объекты, а не сами объекты? Только для того, чтобы в state появилась ссылка на новый массив и React задетектил изменение?

    Именно для этого.
    Ответ написан
  • Как менять состояние isFetching внутри одного редьюсера?

    rockon404
    @rockon404 Куратор тега React
    Frontend Developer
    Состояние коллекции пользователей лучше хранить в одном редьюсере.
    Если в приложение подразумевается работа с одной активной сущностью, то для нее лучше сделать отдельный редьюсер. В этом случае может быть удобным использовать один ключ для редактирования, сохранения и удаления.
    Если подобные ключи нужны для работы с коллекцией, например быстрое редактирование, добавление и удаление в таблице. То можно использовать коллекцию состояний:
    {
      isFetching: {
        'ALL': false,
        '122bc-e43gf-24002-12ea1-ca785': true,
      },
    }

    Где всегда есть свойство для всех сущностей и опционально добавляется для нужных элементов по id.
    Ответ написан
    Комментировать
  • Как исправить ошибку Plugin/Preset files are not allowed..?

    rockon404
    @rockon404 Куратор тега React
    Frontend Developer
    Вам надо снести старые пресеты babel-preset-stage-0 и babel-preset-env, и поставить @babel/preset-stage-0.
    Как правильно написать конфигурацию сотрите в репозитории babel-loader.

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

    rockon404
    @rockon404 Куратор тега React
    Frontend Developer
    В calculateCalories вместо вызова setState следует возвращать вычисленное состояние:
    class Day extends React.Component {
      state = this.calculateCalories();
    
      calculateCalories() {
        /* ... */
        return {
          calories,
          fat,
          protein,
          carbs,
        };
      }
    
      handleClick = () => {
        this.setState(this.calculateCalories());
      };
      
      render() {
        ...
      }
    }


    Еще почитайте про статический метод getDerivedStateFromProps. Возможно подойдет.

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

    rockon404
    @rockon404 Куратор тега React
    Frontend Developer
    Видимо, потому что на странице отсутствует возможность скролла. Весь контент помещается в высоту окна.
    Если это так, то для подобных кейсов используют событие mousewheel. Для кроссбраузерной обработки этого события, если важна одинаковая скорость скролла в разных браузерах, надо использовать адаптер, вроде normalize-wheel
    Ответ написан
    Комментировать
  • Массивы объектов в state - как обновлять?

    rockon404
    @rockon404 Куратор тега React
    Frontend Developer
    Умные люди научили меня не мутировать state и делать примерно так

    Как вы уже могли догадаться по ответам, это не самый оптимальный метод. Даже неправильный.
    Так компоненты в свойствах которых не было никаких изменений будут перерисованы.

    против такого способа выступает официальная документация, где сказано - не мутируй state и избегай forceUpdate(), это может привести к непрогнозируемым багагм.
    Так я хочу спросить - ПОЧЕМУ так нельзя делать и КАКИЕ негативные последствия это может иметь?

    Ну вы же сами пишите, что читали, что это может привести к непрогнозируемым багам.

    Мне кажется, что в простых ситуациях, мутация state и немедленный вызов forceUpdate() будет работать не хуже setState, при этом код будет внятней и эффективней.

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

    Если вам нравится подход с мутациями, то вы можете попробовать использовать с React библиотеку MobX.
    Ответ написан
    2 комментария
  • Как на одной из страниц убрать footer?

    rockon404
    @rockon404 Куратор тега React
    Frontend Developer
    Условный рендеринг.

    Оберните App в withRouter:
    export default withRouter(App);

    Добавьте условие:
    const shouldShowFooter = this.props.location.pathname !== '/basket';

    Отображайте футер по условию:
    {shouldShowFooter && <Footer />}
    Ответ написан
    Комментировать
  • Как демонтировать компонент после его скрытия?

    rockon404
    @rockon404 Куратор тега React
    Frontend Developer
    Подъем состояния:
    const Foo = () => {
      const [shouldShowBar, setShouldShowBar] = useState(true);
    
      const handleBarClose = useCallback(() => {
        setShouldShowBar(false);
      }, []);
    
      return (
        <>
          {shouldShowBar && <Bar onClose={handleBarClose} />}
        </>
      );
    };


    Если это простое модальное окно, которое надо показывать по клику и подобные окна планируется использовать во многих местах, то для удобства их использования можно реализовать обертку, в которой будет использоваться прием render-props:
    const Foo = ({ onConfirm }) => {
      return (
        <ModalWrapper
          onConfirm={onConfirm}
          body="Hello"
        >
          {showModal => (
            <Button onClick={showModal}>Show modal</Button>
          )}
        </ModalWrapper>
      );
    }

    Это позволит не плодить во всех компонентах, где одни будут использоваться, логику их состояния.
    Ответ написан
    3 комментария
  • Какой хостинг выбрать для приложения на реакт?

    rockon404
    @rockon404 Куратор тега React
    Frontend Developer
    Если это билд create-react-app, то будет. Create React App: Deployment
    Если это билд изоморфного приложения с SSR и express сервером, то нет.
    Если третий вариант, то надо больше деталей, чтобы сказать точно.

    Что-то изменится если это будет блог/интернет-магазин?

    Если нужна нормальная индексация в поисковых системах или шаринг в социальных сетях, то нужен SSR или пререндер страниц. Тут простым хостингом не обойдешься.
    Ответ написан
  • Из-за чего выходит ошибка "TypeError: Cannot read property 'createContext' of undefined"?

    rockon404
    @rockon404 Куратор тега React
    Frontend Developer
    Попробуйте добавить в лоадер
    exclude: /node_modules/
    А в tsconfig.json можно добавить:
    "allowSyntheticDefaultImports": true,
    и использовать нормальный импорт в коде:
    import React from 'react';

    Проблема, насколько понял, в том, что свойство "allowSyntheticDefaultImports" установленно в значение false, лоадер парсит библиотеки в node_modules, а дефолтные импорты React сделать с текущими настройками не может.
    Ответ написан
  • Что первым создаётся в этом js коде ??

    rockon404
    @rockon404 Куратор тега React
    Frontend Developer
    Метод находится в прототипе.
    Конструктор вызывается при создании экземпляра.
    Когда вы создаете экземпляр, прототип уже давно определен.
    Ответ написан
    2 комментария
  • Как сделать searchable select без react-select?

    rockon404
    @rockon404 Куратор тега React
    Frontend Developer
    input + любым способом сверстанный список результатов.
    Интерфейс компонента можно сделать чтобы он по onChange(выбору опции) передавал в хандлер фейковый синтетический event.
    Ответ написан
    Комментировать
  • Делают ли так в React?

    rockon404
    @rockon404 Куратор тега React
    Frontend Developer
    Так тоже лучше не делать. Такая конструкция и читается хуже и в нее трудней вносить изменения. Хандлеры лучше передавать явно.

    Давайте лучше разберем более приближенный к реальности кейс:
    const Comment = ({ comment, meta, author, postLike, me }) => {
      const [shouldShowReply, setReply] = useState(false);
    
      const toggleReply = useCallback(() => {
        setReply(s => !s);
      }, []);
    
      const handleLikeClick = useCallback(() => {
        postLike(comment.id, me.id);
      }, []);
    
      const isLiked = useMemo(
        () => meta.likes.some(like => like.user_id === me.id),
        [meta.likes],
      );  
    
      return (
        <Wrapper>
          <Avatar src={user.avatar} to={`/users/${user.slug}`} />
          <CommentBody text={comment.body} />
          <Icon name="like" isActive={isLiked} onClick={handleLikeClick} />
          <Button type="link" onClick={toggleReply}>Reply</Button>
          {shouldShowReply && <ReplyForm />}
        <Wrapper/>
      );
    }
    
    const mapStateToProps = (state, ownProps) => ({
      me: meSelector(state),
      author: commentAuthorSelector(state, ownProps),
      meta: commentMetaSelector(state, ownProps),
    });
    
    const mapDispatchToProps = {
      postLike,
    };
    
    export default connect(mapStateToProps, mapDispatchToProps)(Comment);


    Смотрите, что у нас получается, наш комментарий обрабатывает клик по аватару и клики по кнопкам Like и Reply.
    Клик по аватару обрабатывается ссылкой роутера, а благодаря композиции реализация от нас скрыта и мы просто знаем, что в аватар достаточно передать src картинки и ссылку.
    Клик по лайку обрабатывается асинхронной функцией действием, которая подключается с помощью HOC connect.
    Клик по Reply обрабатывается внутренним хандлером компонента и изменяет его состояние.
    На выходе мы имеем интерфейс для комментария подключенного к хранилищу следующего вида:
    <Comment comment={comment} />
    Для не подключенного:
    <Comment
      me={me}
      author={author}
      meta={commentMeta}
      postLike={postLike}
      comment={comment}
    />

    Плоская структура позволяет нам во-первых быстрей анализировать код.
    Во-вторых без лишних телодвижений его изменять, декомпозировать, подключать к state management библиотеке и тд.

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

    И еще - что лучше тут - бинд или стрелочная функция?

    Это есть в документации.
    Ответ написан
    Комментировать