Тернарный оператор показывает за миллисекунды правдивую часть, даже если она ложная


(извините за мой английский)
Я новичок в Reactjs и пытаюсь создать приложение, в котором пользователь может создавать карточки.
У карточек должна быть категория, поэтому, когда пользователь входит в меню, чтобы перечислить и создать карточки, если не создана какая-либо категория, я хочу показать фразу для доступа пользователя перед меню категории, чтобы создать категорию.
Для этого мой компонент со списком карточек получает Prop со списком категорий, и если список пуст, он показывает баннер, если нет, показывает остальную часть компонента:

type Props = {
          categorias: Categoria[];
        };
        
const TarjetasList = ({ categorias }: Props) => { ...
    return (
        <>
          {!categorias.length ? (
            <h1>Debe crear una categoria</h1>
          ) : (
            <>
              <TarjetaFilter onSubmitFilter = {handleSubmitFilter} />
              <div>
                {page?.content.map((tarjeta) => (
                  <div key = {tarjeta.id}>
                    <TarjetaCard tarjeta = {tarjeta} onDelete = {getTarjetas} />
                  </div>
                ))}
              </div>
              <Pagination
                pageCount = {page ? page?.totalPages : 0}
                range = {2}
                onChange = {handlePageChange}
              />
            </>
          )}
        </>
      );
    };

Проблема в том, что когда пользователь обращается к меню со списком карточек, он показывает баннер с фразой «Вы должны создать категорию» в течение нескольких миллисекунд, хотя «!categoria.length» имеет значение false, а затем останавливается. отобразите его, и он отобразит остальную часть компонента так, как должен, но даже если это всего на несколько миллисекунд, я хочу этого избежать. Является ли это возможным? Что я делаю не так?

вот код компонента меню открывающего список карт:

const Tarjetas = () => {
  const [categorias, setCategorias] = useState<Categoria[]>([]);

  const getCategorias = useCallback(() => {
    const config: AxiosRequestConfig = {
      method: "GET",
      url: "/categorias",
      withCredentials: true,
    };

    requestBackend(config).then((response) => {
      setCategorias(response.data.content);
    });
  }, []);

  useEffect(() => {
    getCategorias();
  }, [getCategorias]);

  return (
    <Routes>
      <Route index element = {<TarjetasList categorias = {categorias} />} />
      <Route path = ":tarjetaId" element = {<TarjetasForm />} />
    </Routes>
  );
};

Вот полный код компонента TarjetasList:

type ControlComponentsData = {
  activePage: number;
  filterData: TarjetaFilterData;
};

type Props = {
  categorias: Categoria[];
};

const TarjetasList = ({ categorias }: Props) => {
  const [page, setPage] = useState<SpringPage<Tarjeta>>();
  const [controlComponentsData, setControlComponentsData] =
    useState<ControlComponentsData>({
      activePage: 0,
      filterData: { texto: "", categoria: null },
    });

  const getTarjetas = useCallback(() => {
    const config: AxiosRequestConfig = {
      method: "GET",
      url: "/tarjetas",
      withCredentials: true,
      params: {
        page: controlComponentsData.activePage,
        size: 3,
        categoriaId: controlComponentsData.filterData.categoria?.id,
        texto: controlComponentsData.filterData.texto,
      },
    };

    requestBackend(config).then((response) => {
      setPage(response.data);
    });
  }, [controlComponentsData]);

  useEffect(() => {
    getTarjetas();
  }, [getTarjetas]);

  const handlePageChange = (pageNumber: number) => {
    setControlComponentsData({
      activePage: pageNumber,
      filterData: controlComponentsData.filterData,
    });
  };

  const handleSubmitFilter = (data: TarjetaFilterData) => {
    setControlComponentsData({
      activePage: 0,
      filterData: data,
    });
  };

  return (
    <>
      {!categorias.length ? (
        <h1>Debe crear una categoria</h1>
      ) : (
        <>
          <TarjetaFilter onSubmitFilter = {handleSubmitFilter} />
          <div>
            {page?.content.map((tarjeta) => (
              <div key = {tarjeta.id}>
                <TarjetaCard tarjeta = {tarjeta} onDelete = {getTarjetas} />
              </div>
            ))}
          </div>
          <Pagination
            pageCount = {page ? page?.totalPages : 0}
            range = {2}
            onChange = {handlePageChange}
          />
        </>
      )}
    </>
  );
};

Вы можете добавить состояние loading и установить его в значение true, когда вы вызываете API, и установить его в значение false, когда вы получите результаты. в вашем компоненте вы сначала проверите, загружается ли он, в этом случае вы можете показать индикатор, если нет, а массив пуст, вы показываете div «пожалуйста, создайте категорию»

coglialoro 18.03.2022 22:19
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Навигация по приложениям React: Исчерпывающее руководство по React Router
Навигация по приложениям React: Исчерпывающее руководство по React Router
React Router стала незаменимой библиотекой для создания одностраничных приложений с навигацией в React. В этой статье блога мы подробно рассмотрим...
Массив зависимостей в React
Массив зависимостей в React
Все о массиве Dependency и его связи с useEffect.
0
1
30
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Ваши категории categorias изначально пусты. Пока вы их не загрузите, вы будете отображать текст.

Самое простое возможное решение — инициализировать categorias не пустым списком, а null:

const [categorias, setCategorias] = useState<Categoria[] | null>(null);

Затем вы можете добавить дополнительное состояние рендеринга, пока не будут загружены categorias:

if (!categorias) {
   return <h1>Cargando…</h1>
}

return (
    <>
      {!categorias.length ? (
        <h1>Debe crear una categoria</h1>
      ) : (
    ...

Однако в идеале вы должны обрабатывать состояние загрузки, используя сложные структуры, подобные:

{ isLoading: true, error: null, categorias: [] }

Тогда вы сможете правильно различать, когда отображать индикацию загрузки и когда отображать ошибку загрузки.

Другие вопросы по теме