Ответы пользователя по тегу React
  • Перемещение элементов в массиве с одной позицию на другую, как реализовать?

    Alexandroppolus
    @Alexandroppolus
    кодир
    Т.е., если в массиве 4 элемента, то элемент на 4 позиции перемещать на 1 позицию, а элементы на 1, 2 и 3 позиции перемещать на 2, 3 и 4 позиции соответственно.

    то что ты описал - это не сортировка, а циклический сдвиг. В некоторых случаях (например, если длина массива постоянна) эффективнее не вращать массив, а двигать "указатель на начало"

    ну а если таки нужно менять массив, то splice+push. Если иммутабельно, то ещё предварительно const newArr = [...arr]
    Ответ написан
  • Почему пропадает фокус с инпута при изменении состояние useState?

    Alexandroppolus
    @Alexandroppolus
    кодир
    Когда печатаешь в первом инпуте, меняется item.from. А он у тебя используется как key для CTableRow. При изменении ключа компонент не обновляется, а перемонтируется (т.е. сносится полностью и создается заново). Возможно, ты хотел для key использовать item.id? тогда было бы норм.
    Ответ написан
    1 комментарий
  • Как отрабатывает сборщик мусора в React?

    Alexandroppolus
    @Alexandroppolus
    кодир
    1. ...
    удалит ли сборщик мусора переменную user ? после того как функция отдаст разметку
    не сразу.
    "разметка" (и примкнувшая к ней строка) будет храниться в дереве VDOM до следующего перерендера Test, чтобы выполнить согласование.

    2....
    как в этом случае поступит сборщик? и как лучше организовывать работу в плане оптимизации памяти

    здесь объект строки постоянный, один и тот же, и не зависит от рендеров. Каждая новая "разметка" будет ссылаться на одну и ту же строку.
    Ответ написан
    Комментировать
  • EsBuild как правильно настроить svg/png?

    Alexandroppolus
    @Alexandroppolus
    кодир
    У тебя там svgrPlugin(), он преобразует svg в реактовские компоненты. Попробуй убрать его из конфига
    Ответ написан
  • Почему в массив не добавляются все коллекции?

    Alexandroppolus
    @Alexandroppolus
    кодир
    ты на каждой итерации forEach добавляешь doc.data() к пустому массиву data.

    const [data, setData] = useState([]);
    const takeData = async () => {
        const UID = getAuth().currentUser.uid;
        const db = getFirestore();
        const q = query(collection(db, "users", UID, "statistic"));
    
        const querySnapshot = await getDocs(q);
        setData(querySnapshot.map((doc) => doc.data()));
      };
      useEffect(() => {
        takeData();
      }, []);
    Ответ написан
  • Нормально ли логировать что-либо в лямбде передаваемой в setState?

    Alexandroppolus
    @Alexandroppolus
    кодир
    С точки зрения useCallback, первый вариант (который с лямбдой) безусловно лучше - мемоизованная функция не меняется при смене isOpen.
    Но разработчики Реакта увещевают нас не делать побочных эффектов в лямбде для setState, т.е. оставить функцию чистой. Подробности тут: https://beta.reactjs.org/reference/react/useState . Здесь же говорится, то в строгом режиме будет наркомания с двойным вызовом лямбды.

    попробуй так:
    const onOpen = useCallback(() => {
      let value = false;
      setIsOpen(open => {
        value = open;  // как я понял, отправлять надо старое значение
        return !open;
      });
      Promise.resolve().then(() => logger.send(value));
    }, []);
    Ответ написан
  • Как передать данные через react-router?

    Alexandroppolus
    @Alexandroppolus
    кодир
    проще всего через контекст

    function App() {
        ......
        return (
             <div ...>
                   <ModalActiveCtx.Provider value={setModalActive}>
                             <Outlet />
                   </ModalActiveCtx.Provider>
                  ........
              </div>
        ); 
    }


    в Main вытащить значение через useContext
    Ответ написан
  • Как оптимизировать перерисовку в цикле?

    Alexandroppolus
    @Alexandroppolus
    кодир
    Этот материал читал.

    вроде должно подойти (см. там вариант с useMemo)

    только у тебя параметр для мемоизации - не примитивное значение, а объект (position, он же dish). Потому укажи кастомный serializer, который просто возвращает position.id.

    в целом способ прикольный, но надо помнить, что в отрендеренном родительском компоненте (в твоем примере - Category) мемоизация будет жить постоянно до размонтирования. И если будут часто меняться ключи, а компонент будет жить очень долго, то в кэше накопится много элементов. На этот случай в опциях fast-memoize можно задать свой кастомный кэш с ограничением на размер и удалением старых элементов. Впрочем, полагаю, в твоем случае до такого не дойдет.
    Ответ написан
    3 комментария
  • Поле current у ref перезаписывается, как этого избежать?

    Alexandroppolus
    @Alexandroppolus
    кодир
    ты можешь использовать 2 рефа: для дом-элемента и для твоего объекта
    Ответ написан
  • Как оптимизировать списки при повторных рендрах?

    Alexandroppolus
    @Alexandroppolus
    кодир
    Но как показалось, React.memo можно было избежать.

    зачем? здесь оно в самый раз.

    а вообще у тебя какая-то хрень в нейминге. По идее, компонент Position должен быть для каждого элемента массива positions. А то что у тебя называется Position, должно называться Dish, и тоже быть memo
    т.е. так:
    {positions.map(({ id, name, ref, dishes }) => <Position ... />)}


    export const Position = memo(({ ...,  dishes, ... }) => {
    .........
       {dishes.map((item) => <Dish ... />}
    .....
    });


    тогда при изменении чего-то, например, внутри блюда, будет перерендер компонента со списком позиций, перерендер одной позиции с блюдом, и перерендер блюда.
    Это минимум для иммутабельного стейта. Если хочешь совсем упороться и выкинуть перерендер списка, то mobx в помощь.
    Ответ написан
    2 комментария
  • Как вызвать ререндер несвязанного компонента?

    Alexandroppolus
    @Alexandroppolus
    кодир
    Само приложение маленькое, организовывать хранение стейта с помощью условного redux не вижу смысла

    ну тогда просто храни в контексте
    Ответ написан
    Комментировать
  • Как вызвать функцию только раз в useEffect при разных изменениях?

    Alexandroppolus
    @Alexandroppolus
    кодир
    Варианты:
    1) выкинуть на мороз первый useEffect. При смене activeTab (это ведь происходит по клику на каком-то элементе?) заодно делать setPage(1).
    2) дублировать в useRef текущие значения стейта, обновлять во втором эффекте, и не вызывать загрузку при определенной комбинации. Немного костыльный вариант, советую всё таки первый.
    Ответ написан
    Комментировать
  • Дочерние компоненты не видят стор?

    Alexandroppolus
    @Alexandroppolus
    кодир
    У тебя в ParentComponent и в ChildComponent лежат разные экземпляры стора. Просто два разных независимых объекта.

    Разберись, как работает useLocalObservable и в чем его философия. Должно попустить.
    Ответ написан
    Комментировать
  • Как исправить постоянное создание нового соединение вебсокета?

    Alexandroppolus
    @Alexandroppolus
    кодир
    useEffect(() => {
    
        socket.current = new WebSocket(`ws://localhost:8000/message`)
    
        socket.current.onopen = () => {
          console.log('connected')
        };
        
        socket.current.onmessage = (event) => {
          const message = JSON.parse(event.data);
          setMessages((messages) => [...messages, message]);
        };
    
        socket.current.onclose = () => {
          console.log('socket was closed')
        };
    
        socket.current.onerror = () => {
          console.log('socket get some error')
        };
    
        return () => {
            socket.current.close();
        };
      }, [])
    Ответ написан
    Комментировать
  • Почему в styled-components нельзя использовать такую обёртку?

    Alexandroppolus
    @Alexandroppolus
    кодир
    Рискну предположить, что Table - это и есть Component1.

    Ты передаешь в Component1 проп children, но в самом компоненте этот проп, к сожалению, не используется.

    надобно:
    function Component1({children}) {
      return (
    <StyledComponent1>
          <p>Wrapper</p>
          {children}
    </StyledComponent1>
      );
    }


    куда именно воткнуть children внутри Component1 - это уж сам решай, но куда-то придётся.

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

    Alexandroppolus
    @Alexandroppolus
    кодир
    item.price = item.price * item.count


    у тебя стоимость растет пропорционально факториалу )) 1 экземпляр стоит 1 рубль, а 4 экземпляра - уже 24 рубля (это если были только +1, а при нажатиях на -1 будет совсем наркомания).

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

    Alexandroppolus
    @Alexandroppolus
    кодир
    Похоже, у тебя на всё про всё только один useState для modalActive, и при клике по кнопке Info все модалки всплывают на свет божий.

    храни в стейте name (или id) выбранного персонажа
    для модалки устанавливай проп active={item.name === activeName}
    Ответ написан
    Комментировать
  • Когда использовать useReducer, а когда useState?

    Alexandroppolus
    @Alexandroppolus
    кодир
    если новое значение стейта не зависит от текущего значения, то однозначно - useState.

    а если зависит, то useReducer может быть удобнее (как минимум, в ряде случаев позволит обойтись без useCallback), но тут лучше посмотреть на оба варианта и сравнить, какой больше нравится. Хотя вот в простом случае, если в dispatch не нужно кидать параметр, то useReducer явно лучше
    Ответ написан
    Комментировать
  • Как правильно рендерить рекурсивный массив используя useMemo?

    Alexandroppolus
    @Alexandroppolus
    кодир
    reply.replies = [newReply,...reply.replies]
    setReplies(rootReplies=>[...rootReplies])

    ты неправильно обрабатываешь стейт. По факту здесь меняется содержимое некоего узла, а потом возвращается поверхностная копия всего дерева.

    есть 3 варианта:
    1) Продолжать использовать дерево в useState. Но менять его надо иммутабельно. То есть если у какого-то узла что-то поменялось, то надо заменить узел и все его паренты, а не только корневой массив.
    2) Нормализовать данные в плоскую структуру. Каждому реплаю присваивается уникальный id, все реплаи складываются в объект, где ключем будет id. В массиве replies у каждого объекта будут лежать не сами объекты, а только id, и потом надо будет их соединять во время рендера. Этот вариант канонично используется для redux, но как зайдет для useState, навскидку не совсем понятно.
    3) Использовать MobX с этими его observable.deep (или просто observable). Как всегда, самый простой и удобный вариант.
    Ответ написан
    Комментировать
  • Как конвертировать svg в react в двоичное .png?

    Alexandroppolus
    @Alexandroppolus
    кодир
    попробуй закинуть картинку на canvas и потом получить блоб для отправки на бэк
    Ответ написан
    Комментировать