Задать вопрос
@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;
  • Вопрос задан
  • 169 просмотров
Подписаться 1 Простой 1 комментарий
Помогут разобраться в теме Все курсы
  • Яндекс Практикум
    Мидл фронтенд-разработчик
    5 месяцев
    Далее
  • Яндекс Практикум
    React-разработчик
    3 месяца
    Далее
  • Яндекс Практикум
    Фронтенд-разработчик
    10 месяцев
    Далее
Пригласить эксперта
Ответы на вопрос 1
@chemdev
Данная проблема решается состояниями isLoading, isError, isSuccess (последнее в принципе вычисляемое). Есть как ряд библиотек, которые это все поставляют (RTK Query, например), но и можно самому это все дописать к axios, но с большой вероятностью придется писать много повторяющегося кода. Это можно поправить кастомным хуком который даст все состояния за один вызов.
Ответ написан
Комментировать
Ваш ответ на вопрос

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

Похожие вопросы
ITK academy Нижний Новгород
от 80 000 до 120 000 ₽
ITK academy Воронеж
от 50 000 до 90 000 ₽