Ответы пользователя по тегу React
  • Как правильно отправить асинхронный запрос в useEffect?

    @twolegs
    В вашем случае нужно избежать апдейта стейта если компонент был размонтирован. Самое верное, на мой взгляд, решение - это отмена запроса при размонтировании. Пример с fetch, т.к. не знаю, есть ли возможность отменить запрос в axios.
    useEffect(() => {
        const abortController = new AbortController();
        const fetchData = async () => {
          await fetch(url, { abortController }).then((data: any) => {
            setImg(data);
            setPreloader(!preloader);
          });
        };
        fetchData();
    
        return () => {
          abortController.abort(); 
        }
      }, [url]);


    Если рассмотреть пример выше, теоретически должно сработать такое:
    useEffect(() => {
      let isMounted = true; 
      const fetchData = async () => {
       ...
        if (isMounted) {
          setImg(data);
          setPreloader(!preloader);
        }
       ...
      }
      ...
      return () => { isMounted = false; };
    }, [])
    Ответ написан
    Комментировать
  • Как обновить react компонент после изменения в объекте?

    @twolegs
    Во-первых, у вас каждый рендер будет создаваться новый экземпляр объекта FactorModel(). Т.е. каждую итерацию рендера у вас заново инициализированный объект.
    Чтобы этого избежать, надо либо мемоизировать этот инстанс (хук useMemo), либо инстанцировать объект вне компонента (если это возможно).
    Во-вторых, эффект также вызывается каждый рендер, и на событие каждый раз подписывается новая функция (память течет). Чтобы этого избежать, нужно указать второй параметр в useEffect: useEffect(..., []) - такой эффект выполнится только при монтировании компонента.
    Ответ написан
    Комментировать
  • Какой тип нужно выбрать?

    @twolegs
    Использовать generic для MouseEventHandler:
    deleteItem: React.MouseEventHandler<T>
    Где T - нужный вам тип, включающий dataset
    Ответ написан
  • Какая должна быть структура у сайта на React?

    @twolegs
    Как правило, реакт используется для SPA, т.е. single page application. То есть точка входа в приложение одна - index.html, на которой подключается скрипт приложения. Дополнительные адреса, как правило, обрабатываются клиентским роутингом (см. react-router например). Т.е. на все запросы бэкенд будет отдавать index.html, а сам урл будет разбираться на фронте.
    Ответ написан
  • Организация хєндлеров для useContext стейта?

    @twolegs
    Если так много действий, изменяющих стейт - проще будет использовать стейт менеджер, тот же redux например.
    Если redux подключать не хочется, то можно вместо setState использовать useReducer. В этом случае хранить какую-то историю действий и следить за порядком выполнения хэндлеров будет проще.
    Ответ написан
  • Что сделать с reducers?

    @twolegs
    1. Если это независимые списки, то почему после ответа апи promoHeroes перезаписываются? Если идея в том, что инфу на главной всегда показывать из promo, то просто не трогать это поле при HEROES_API_LOADED.
    2. Если же промо-список должен обновляться после запроса к апи, то тут можно реорганизовать стор.
    В идеале - хранить нормализованный список героев. Примерная структура:
    const store = {
      heroes: {
        byId: { 1: { id: 1, name: 'Luke', ... }, ... },
        allIds: [1, 2, 3, ...],
      },
      promoIds: [1, 2],
    }

    Иногда нормализация кажется излишней, и кажется что работать с таким стором сложнее, но на деле это оказывается удобнее.
    Теперь, если сервисы promo и api должны формировать один общий список, то на экшенах HEROES_API_LOADED и HEROES_PROMO_LOADED необходимо мержить эти два списка в одно нормализованное хранилище heroes.
    Даже если не хочется делать нормализацию, но необходимо объединить два списка из разных сервисов, придется писать какую-то логику мержа.
    Ответ написан
    Комментировать