Задать вопрос
Ответы пользователя по тегу React
  • Что делать с ошибкой линтера и какие лучше зависимости включать для useEffect?

    Alexandroppolus
    @Alexandroppolus
    кодир
    Довольно спорная тема. На гитхабе было обсуждение, где Ден увещевал всех забыть про "componentDidMount" и мыслить зависимостями - раз уж компонент по сути отражение текущего стейта.
    В твоём случае ничего не меняется, потому нужно просто добавить эти значения в депсы и не заморачиваться. Диспатч всегда постоянный, так что включай тоже.
    Собственно, проблема может возникнуть, если интересует только значение на момент маунта и ты сознательно не хочешь эффектить при изменении. Тогда можно просто сделать, например, const firstValue = useRef(propValue).current; ,тогда в firstValue у тебя будет только первое значение, которое можно передать в useEffect. Это тоже костыль, но более явный код, чем еслинт-дизабл.
    Ответ написан
    Комментировать
  • Как сделать прокрутку к определенному блоку?

    Alexandroppolus
    @Alexandroppolus
    кодир
    useEffect(() => {
        if (component === 'aboutCompany') {
                clickToAboutCompanyBlock()
        }
    }, [component])
    Ответ написан
    Комментировать
  • Как передать функцию с сервера на клиент при SSR?

    Alexandroppolus
    @Alexandroppolus
    кодир
    Странная хотелка. Это требование SEO - калькулятор должен индексироваться поисковиками? Или для вычислений нужно дохрена данных, и проще вычислить на сервере, чем передать их клиенту? Во всех прочих кейсах считать удобнее на фронте.
    И что значит передать функции? Какие-то формулы? Они генерятся динамически?
    Ответ написан
  • Как правильно передавать контекст в subChild компоненты, находящиеся в других модулях?

    Alexandroppolus
    @Alexandroppolus
    кодир
    Похоже, ты не понял, зачем контекст вообще нужен.
    Он позволяет передать значение на несколько уровней вниз. При этом, если значение в контексте поменяется, то будет перерендер всех компонентов, которые его используют.
    Можно передавать и некоторое постоянное значение, например экземпляр какого-нибудь стора, как это делает тот же реакт-редукс. В этом случае не используется отслеживание смены значения (оно постоянное), но есть архитектурная польза - это такой своеобразный DI в вёрстку. Который, например, можно поменять в тестах или ещё где. То есть компонент не прибивается гвоздями к заимпорченому значению, а получает его в параметры, с позднейшим резолвом зависимости.
    Ответ написан
    Комментировать
  • Как убрать процессы запущенные уже удаленным скриптом внутри SPA в React?

    Alexandroppolus
    @Alexandroppolus
    кодир
    Запоминать факт, что этот сторонний код был добавлен, и больше не добавлять. Можно просто не удалять тег.
    В общем случае, этот код завернут в IIFE, и залезть внутрь него не получится. Если он не проверяет какие-то внешние флаги, не взаимодействует с внешними переменными и функциями, то никак. А если взаимодействует, то надо смотреть по ситуации, что там конкретно.
    Ответ написан
    Комментировать
  • В чём отличие хука useMemo от useCallback в React?

    Alexandroppolus
    @Alexandroppolus
    кодир
    Отличий два
    1) useCallback(func, deps) - ни что иное как useMemo(() => func, deps)
    То есть useCallback возвращает функцию, а useMemo выполняет функцию и возвращает результат (в обоих случаях - при условии что депсы поменялись).
    2) про useMemo в документации есть предостережение, что Реакт не гарантирует сохранность результата и может вычислить ещё раз, даже при неизменных депсах. Про useCallback такого не сказано.
    Ответ написан
    Комментировать
  • Некорректно работает css transition в React, что может быть?

    Alexandroppolus
    @Alexandroppolus
    кодир
    Непонятно, как там форкнуться, потому вот исправленный код
    г-код Дотс.джсх

    import React, { useMemo } from "react";
    import * as S from "./dots.style";
    
    function makeData(dots, shift, width) {
      const normShift = shift >= 0 ? shift : shift - dots.length * shift;
      return dots.map((dot, index) => ({
        key: dot,
        isFirst: index === 0,
        isLast: index === dots.length - 1,
        left: ((normShift + index) % dots.length) * width
      }));
    }
    
    export const Dots = ({ dots, shift }) => {
      const data = useMemo(() => makeData(dots, shift, 25), [dots, shift]);
    
      return (
        <S.Container>
          {data.map(({ key, left, children }) => (
            <S.Dot key={key} left={left}>
              {key}
            </S.Dot>
          ))}
        </S.Container>
      );
    };



    проблема была вот в чем: переназначались key для элементов. Потому некоторые элементы оставались как есть и просто апдейтились, а некоторые пересоздавались (реакт не умеет перекидывать одни элементы через другие). Потому key надо сохранять, а просто менять left у всех
    Ответ написан
  • Как иммутабельно удалить обьект по ключу из стора redux?

    Alexandroppolus
    @Alexandroppolus
    кодир
    Да, delete будет мутировать стор.

    проще всего сделать поверхностную копию объекта и уже из неё удалить:
    if (state.key[objKey]) {
      const copy = {...state.key};
      delete copy[objKey];
      return { ...state, key: copy };
    }
    Ответ написан
    1 комментарий
  • Как запустить async функцию внутри map?

    Alexandroppolus
    @Alexandroppolus
    кодир
    <img src={getImage(el.id)} /> поместить в отдельный реактовский компонент, например, StorageImage. Далее возможны различные варианты в зависимости от того, что используется на проекте. Наиболее простой - useQuery - это обеспечит кэширование и обновление стейта из коробки, и все остальные детали, прям вот всё что нужно для данного кейса.
    Ответ написан
    3 комментария
  • Как оптимизировать вычисления в функциональном компоненте?

    Alexandroppolus
    @Alexandroppolus
    кодир
    Помимо сделанного WbICHA разбора функций (сурового, но справедливого), накину ещё чисто реактовских поинтов:
    1) функции с вычислениями выселить нахрен из компонента, передавать в них данные.
    2) Пачка стейтов (average... median) - ни что иное как богомерзкие производные стейты, подлежащие перековке на useMemo, с выбросом на помойку того useEffect, в котором calculation().
    3) isConnectionStarted выглядит как лишний. По крайней мере, это не стейт. Возможно, стоит его переделать в ref
    4) Назначение statistic непонятно. Подозреваю, что он не нужен, так как дублирует data.length (признак наличия данных).
    5) Работу с вебсокетом было бы хорошо вынести в отдельный класс с логикой. Экземпляр класса хранить, например, в ref.
    6) в функции старт какая-то ересь внутри ифа
    Ответ написан
    1 комментарий
  • Как размонтировать, то что находится не в useEffect?

    Alexandroppolus
    @Alexandroppolus
    кодир
    Проблема в том, что ты запускаешь асинхронные действия в useEffect. Это не очень правильно, логику лучше выносить отдельно, а её результаты складывать в стор.

    Если нужно очень быстро пофиксить без рефакторинга, то можно добавить проверку на размонтирование, чтобы не менять стейт размонтированного компонента.
    const useCheckMounted = (): (() => boolean) => {
      const ref = useRef(true)
      useLayoutEffect(() => {
        ref.current = true
        return () => {
          ref.current = false
        }
      }, [ref])
      return useCallback(() => {
        return ref.current
      }, [ref])
    }
    
    // пример использования:
    const Child: React.FC = React.memo(() => {
      const check = useCheckMounted()
    
      useEffect(() => {
        console.log('check1, ', check())
        setTimeout(() => {
          console.log('check2, ', check())
        }, 8000)
      }, [check])
    
      return <div>child</div>
    })


    этот компонент запускает setTimeout, символизирующий долгий запрос. Перед запуском check() возвращает true - компонент смонтирован. При ответе сервера check() вернет false, если компонент слетел, или true, если ещё жив.
    Пример на TS, если что - просто убери типы
    Ответ написан
  • Правильно ли использвать async await при работе с callbacks?

    Alexandroppolus
    @Alexandroppolus
    кодир
    async-функция возвращает промис, только и всего. Если onClick это по барабану, то всё норм.
    Ответ написан
    Комментировать
  • Почему происходит ре-рендер при изменении массива в useSelector?

    Alexandroppolus
    @Alexandroppolus
    кодир
    надо проверять, что массивы не равны. Сделал поверхностное сравнение. Возможно, понадобится ещё и вглубь элементов, но это детали. В общем, сравнивай массивы.

    const isShallowEqualArrays = (arr1, arr2) =>
        arr1 === arr2 || (arr1.length === arr2.length && arr1.every((v, i) => v === arr2[i]));
    
    export const mainReducer = (state = initialState, action) => {
        if (action.type === SET_COUNT) {
            if (!isShallowEqualArrays(state.count, action.count)) {
                return {
                    ...state,
                    count: action.count
                };
            }
        }
        return state;
    };
    Ответ написан
    1 комментарий
  • Как предотвратить ре-рендер компонента state которого меняется в другом дочернем компоненте?

    Alexandroppolus
    @Alexandroppolus
    кодир
    убрать данный useState из MainPage

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

    useCallback и React.memo тоже понадобятся. Есть смысл мемоизить Table, он очень жирный. Соответственно для создания sortData не обойтись без useCallback.

    есть и другие приколы. Например, sortUpData и прочие хелперы. Там мутабельно сортируется массив. Да-да, arr.sort(...) возвращает тот же самый объект массива, предварительно отсортировав. Это может приводить к потере перерендеров при изменении состояния. Для иммутабельности надо так: arr.slice().sort(...) - тут создается копия и сортируется.

    прочее не смотрел, но не удивлюсь, если ещё есть какая ересь на местах..
    Ответ написан
    Комментировать
  • Как обновить дочернюю компоненту react из дочерней компоненты?

    Alexandroppolus
    @Alexandroppolus
    кодир
    header не меняется, я понял в чём причина, ведь он отрисовался вначале и не отрисовывался больше
    вообще-то он должен меняться, в этом суть реакта

    замени идиотский тернарник на < HeaderComponent logged={this.state.logged}/ > . Не факт, что это поможет, конечно. Проблема где-то ещё. console.log точно срабатывает?
    Ответ написан
  • Почему не приходит значение в useState?

    Alexandroppolus
    @Alexandroppolus
    кодир
    Всё то же самое, как и здесь https://qna.habr.com/q/1041970

    конкретно в данном случае const [userss, setUserss] = useState(users.data); выглядит как лишний, ведь можно пользоваться тем же самым users. setData, то есть стейт уже есть
    Ответ написан
    5 комментариев
  • Как сделать несколько запросов в js?

    Alexandroppolus
    @Alexandroppolus
    кодир
    let [data, setData] = useState([]);
    useEffect(() => { setData(getNews()); }, []);


    У тебя в data попадет промис.

    Всё-таки использовать async/await следует, только разобравшись с промисами и вообще с асинхронностью...
    Ответ написан
    Комментировать
  • Как правильно передать функцию хука через props к дочернему компоненту?

    Alexandroppolus
    @Alexandroppolus
    кодир
    Надо бы протипизировать по нормальному. Встала на праведную стезю TS - забудь про всякие any.

    ...
    <RegulationEditWindow setIsEditing={setIsEditing} />
    ...


    interface RegulationEditWindowProps {
        setIsEditing(editing: boolean): void;
    }
    
    const RegulationEditWindowView: React.FC<RegulationEditWindowProps> = React.memo((props) => {
        ...
        <ArrowLeftOutlined onClick={() => props.setIsEditing(false)} />
        ...
    });
    Ответ написан
    5 комментариев
  • Появился новая ошибка в реакте?

    Alexandroppolus
    @Alexandroppolus
    кодир
    Где-то есть импорт (или require) файла "../reading-list/page", но этого файла нет. Возможно, ошибочно указан путь, например, надо одну точку вместо двух, или наоборот докинуть ещё двоеточий.
    Если такой файл точно есть, то надо перезапустить консоль, в которой делается сборка - она могла закэшировать файловую структуру или что-то подобное, и теперь не хочет пересматривать.
    Ответ написан