Задать вопрос
@morbiuslevakov

Как показать preloader до загрузки страницы?

Я получаю цены и балансы через API, но при первой загрузке react выдает ошибку, поскольку localStorage не содержит этих объектов. Подскажите пожалуйста, как дождаться загрузки данных из API и показать preloader, пока данные не загрузятся. Буду благодарен за любой совет/ответ.
Вот мой код:
Wallet:
class Wallet extends React.Component {
    constructor(props) {
        super(props);
        this.state = {
            // state elements
        }
    }
    
    render() {
        const user = JSON.parse(localStorage.getItem("user"));

        if (!user) {
            return <Navigate to="/login" />;
        }

        const { dispatch, history } = this.props;
        
        PriceService.setPrices(this.state.fiat).then(
            response => {
                localStorage.setItem("crypto", JSON.stringify(response.data))
            }, error => {
                if (error.response.status === 403) {
                    EventBus.dispatch("logout");
                    if (!user) {
                        history.push("/register");
                        window.location.reload();
                    }
                }
            }
        );
        PriceService.setBalances(user?.address).then(
            response => {
                localStorage.setItem("balance", JSON.stringify(response.data))
            }, error => {
                if (error.response.status === 403) {
                    EventBus.dispatch("logout");
                    if (!user) {
                        history.push("/register");
                        window.location.reload();
                    }
                }
            }
        );
        
        return (
            <Suspense fallback={<Preloader/>}>
                <div className="content-container">
                    <TableContainer className="table-container">
                        <Table aria-label="simple table">
                            <TableHead>
                                <TableRow>
                                    <TableCell align="left">Name</TableCell>
                                    <TableCell align="left">Price</TableCell>
                                    <TableCell align="left">Amount</TableCell>
                                </TableRow>
                            </TableHead>
                            <TableBody>
                                {
                                    Array.from(Object.entries(JSON.parse(localStorage.getItem("crypto")).assets)).map((value) => {
                                        return (
                                            <TableRow key={value[0]} sx={{'&:last-child td, &:last-child th': {border: 0}}}>
                                                <TableCell align="left">{value[0]}</TableCell>
                                                <TableCell align="left">{value[1].price.toFixed(2)}</TableCell>
                                                <TableCell align="left">
                                                    {
                                                        new Map(Object.entries(JSON.parse(localStorage.getItem("balance")).balance)).get(value[0]).balance
                                                    }
                                                </TableCell>
                                            </TableRow>
                                        )
                                    })
                                }
                            </TableBody>
                        </Table>
                    </TableContainer>
                </div>
            </Suspense>
        );
        
    }
}

function mapStateToProps(state) {
    const { isLoggedIn } = state.auth;
    const { message } = state.message;
    return {
        isLoggedIn,
        message
    };
}
export default connect(mapStateToProps)(Wallet);


PriceService:
class PriceService {
    setPrices = (currency) => {
        return api.get("/price/crypto/" + currency);
    }
    setBalances = (address) => {
        return api.get("/asset/get-assets?address=" + address);
    }
}

const priceService = new PriceService();
export default priceService;


api:
import axios from "axios";
import TokenService from "./token.service";

const instance = axios.create({
    baseURL: "http://localhost:8080/api",
    headers: {
        "Content-Type": "application/json",
    },
});

instance.interceptors.request.use(
    (config) => {
        const token = TokenService.getLocalAccessToken();
        if (token) {
            config.headers["Authorization"] = 'Bearer ' + token;
        }
        return config;
    },
    (error) => {
        return Promise.reject(error);
    }
);

instance.interceptors.response.use(
    (res) => {
        return res;
    },
    async (err) => {
        const originalConfig = err.config;

        if (originalConfig.url !== "/auth/signin" && err.response) {
            // Access Token was expired
            if (err.response.status === 401 && !originalConfig._retry) {
                originalConfig._retry = true;

                try {
                    const rs = await instance.post("/auth/refresh-token", {
                        refreshToken: TokenService.getLocalRefreshToken(),
                    });

                    const { accessToken } = rs.data;
                    TokenService.updateLocalAccessToken(accessToken);

                    return instance(originalConfig);
                } catch (_error) {
                    return Promise.reject(_error);
                }
            }
        }

        return Promise.reject(err);
    }
);

export default instance;
  • Вопрос задан
  • 170 просмотров
Подписаться 1 Простой 1 комментарий
Помогут разобраться в теме Все курсы
  • Яндекс Практикум
    Мидл фронтенд-разработчик
    5 месяцев
    Далее
  • Javascript.ru
    Курс по React
    5 недель
    Далее
  • Нетология
    Fullstack-разработчик на Python + нейросети
    20 месяцев
    Далее
Пригласить эксперта
Ответы на вопрос 1
@chemdev
Данная проблема решается состояниями isLoading, isError, isSuccess (последнее в принципе вычисляемое). Есть как ряд библиотек, которые это все поставляют (RTK Query, например), но и можно самому это все дописать к axios, но с большой вероятностью придется писать много повторяющегося кода. Это можно поправить кастомным хуком который даст все состояния за один вызов.
Ответ написан
Комментировать
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы
ITK academy Нижний Новгород
от 50 000 до 90 000 ₽
IT ATLAS Москва
от 200 000 до 250 000 ₽
ITK academy Казань
от 50 000 до 90 000 ₽