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

Я использую экран загрузки для этого компонента при использовании fetch.

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

Я новичок в следующем js, и я использую API с экспресс-загрузкой всех данных на следующий веб-сайт js.

'use client';

import HeaderStyle from './Header.module.scss';
import { LoadingScreen } from '../LoadingScreen/LoadingScreen';
import Link from 'next/link';
import { usePathname } from "next/navigation";
import { useState, useEffect, createRef} from 'react';
import { UrlObject } from 'url';

function Header(): JSX.Element {

    const [data, setData] = useState(null)
    const [isLoading, setLoading] = useState(false)

    useEffect(() => {
        setLoading(true)
        fetch('http://localhost:5000/getNavegation')
          .then((res) => res.json())
          .then((data) => {
                setData(data)
                setLoading(false)


          })
      }, 
    [])

    if (isLoading) return <LoadingScreen />;
    if (!data) return <header></header>;


    return (
        <header id = {HeaderStyle.header}>

            <div className = {HeaderStyle.logo}>
                <Link href = "/" className = {HeaderStyle.logoname}>Pedro Alves</Link>
            </div>

            <div ref = {menu} className = {HeaderStyle.menu}>

            {
            data.map((link: { url: string | UrlObject; name: string}, index: number) => (
                <Link key = {index} className = {HeaderStyle.link} href = {link.url}>{link.name}</Link>
            ))}

            </div>

            <div className = {HeaderStyle.toggle_menumobile}>
                <span ref = {toggle_menumobile} className = "icon-base menu-icon"></span>
            </div>

        </header>
    )

}


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

Ответы 1

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

Путь «Next.js»

Из-за того, что вы используете внешний API и используете реакцию на стороне клиента для управления состоянием загрузки, будет сложно сделать это способом «Next.js». Если вы хотите сделать это способом «Next.js», вызовы API необходимо будет выполнять на сервере next.js либо с помощью getServerSideProps, либо с помощью перехватчика HTTP, либо с помощью любого другого метода. Но это не похоже на то, что вы пытаетесь сделать здесь, и использование двух разных API для этого можно считать антипаттерном. Поэтому вместо этого мы сделаем это способом реагирования.

«Реактивный» путь

Можно создать поставщика LoadingScreen, который удаляет повторяющийся код, с которым вы сталкиваетесь каждый раз, когда хотите показать экран загрузки. Вы используете хук «useLoadingScreen» и используете метод «setLoading» вместо переменной «isLoading», которую вы использовали ранее. Я буду использовать для этого React usecontext, так как это универсальное решение. Но если вы используете глобальную библиотеку управления состоянием, такую ​​как redux, react-query, jotai или swt, не стесняйтесь реализовывать ее с вашей соответствующей библиотекой.

LoadingProvider.tsx

import React, { createContext, useContext, useState } from 'react'
import LoadingScreen from '...../LoadingScreen/LoadingScreen';

type LoadingScreenProps = {
    loading: boolean;
    setLoading: (loading: boolean) => void
}

export const LoadingScreenContext = createContext<LoadingScreenProps>({
    loading: false,
    setLoading: () => null,
})
export const useLoadingScreen = () => useContext(LoadingScreenContext)

export const LoadingScreenProvider = ({ children }: { children: React.ReactNode }) => {
    const [loading, setLoading] = useState<boolean>(false)

    if (loading) return <LoadingScreen />

    return (
        <LoadingScreenContext.Provider value = {{ loading, setLoading }}>
            {children}
        </LoadingScreenContext.Provider>
    )
}

Обязательно обновите файл «App.tsx» соответствующим образом, заключив основной компонент с вашим провайдером.

            <LoadingScreenProvider>
              <Component {...pageProps} />
            </LoadingScreenProvider>

Обновленный вариант использования

'use client';

import HeaderStyle from './Header.module.scss';
import { LoadingScreen } from '../LoadingScreen/LoadingScreen';
import Link from 'next/link';
import { usePathname } from "next/navigation";
import { useState, useEffect, createRef} from 'react';
import { UrlObject } from 'url';
import { useLoadingScreen } from '....../LoadingProvider.tsx'

function Header(): JSX.Element {

    const [data, setData] = useState(null)
    const { setLoading } = useLoadingScreen;


    useEffect(() => {
        setLoading(true)
        fetch('http://localhost:5000/getNavegation')
          .then((res) => res.json())
          .then((data) => {
                setData(data)
                setLoading(false)


          })
      }, 
    [])

    if (!data) return <header></header>;


    return (
        <header id = {HeaderStyle.header}>

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