Сообщите об окончании асинхронной загрузки интерфейсу React

Существует класс под названием JSONHeader, с которого мы загружаем каждый из JSON:

import jQuery from 'jquery-ajax';
import Atlas from "./Atlas";

export default class JSONHeader {
    constructor(location) {
        loadAtlasStructure(location);

        function loadAtlasStructure(location) {
            jQuery.ajax({
                dataType: "json",
                url: location,
                async: true,
                success: function (files) {
                    files.map((file) => {
                        jQuery.ajax({
                            dataType: "json",
                            url: location + file,
                            async: true,
                            success: function (data) {
                                console.info(data);
                                if (!window.IndexAtlas) {
                                    window.IndexAtlas = new Atlas();
                                }
                                window.IndexAtlas.addSubAtlas(data);
                                console.info('JSONHeader::window.IndexAtlas', window.IndexAtlas);
                            }
                        });
                    })
                }
            })
        }
    }
}

И я хотел бы изменить компонент верхнего уровня React: App с isLoading: true на isLoading: false после загрузки всех json. Как мы могли добиться такого поведения? В настоящее время я заставляю ждать 5 секунд каждый раз, когда мы перезагружаем все JSON.

import React, {Component} from 'react';
import BrowserRouter from "react-router-dom/es/BrowserRouter";
import Switch from "react-router-dom/es/Switch";
import Route from "react-router-dom/es/Route";
import Redirect from "react-router-dom/es/Redirect";
import ScenePage from "../ScenePage/index";
import CoverPage from "../CoverPage/index";
import {INDEX, SCENE_PAGE} from "../../constantRoutes";
import JSONHeader from "../../newModel14Junio/JSONHeader";

export default class App extends Component {
    constructor(props) {
        super(props);

        const header = new JSONHeader('/atlas/json/');

        this.state = {
            isAtlasLoading: true
        };

        setTimeout(() => {
            this.setState({isAtlasLoading: false});
        }, 5000);
    }

    render() {
        if (this.state.isAtlasLoading) {
            return (<div>Atlas loading</div>);
        }
        return (
            <BrowserRouter>
                <div>
                    <Switch>
                        <Route exact path = {INDEX} component = {CoverPage}/>
                        <Route path = {SCENE_PAGE} component = {() => <ScenePage IndexAtlas = {window.IndexAtlas}/>}/>
                        <Redirect from = "*" to = {INDEX}/>
                    </Switch>
                </div>
            </BrowserRouter>
        );
    }
}

Спасибо за помощь.

Вы можете передать обратный вызов JSONHeader, и там, когда он закончится, вы вызовете его

Matheus Pitz 15.06.2018 13:19
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
В настоящее время производительность загрузки веб-сайта имеет решающее значение не только для удобства пользователей, но и для ранжирования в...
Безумие обратных вызовов в javascript [JS]
Безумие обратных вызовов в javascript [JS]
Здравствуйте! Юный падаван 🚀. Присоединяйся ко мне, чтобы разобраться в одной из самых запутанных концепций, когда вы начинаете изучать мир...
Система управления парковками с использованием HTML, CSS и JavaScript
Система управления парковками с использованием HTML, CSS и JavaScript
Веб-сайт по управлению парковками был создан с использованием HTML, CSS и JavaScript. Это простой сайт, ничего вычурного. Основная цель -...
JavaScript Вопросы с множественным выбором и ответы
JavaScript Вопросы с множественным выбором и ответы
Если вы ищете платформу, которая предоставляет вам бесплатный тест JavaScript MCQ (Multiple Choice Questions With Answers) для оценки ваших знаний,...
0
1
121
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

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

Использовать для этого тайм-аут - не лучшая идея, потому что вы не знаете, сколько времени уйдет на завершение. Итак, вы можете добавить обратный вызов в свой JSONHeader, например:

import jQuery from 'jquery-ajax';
import Atlas from "./Atlas";

export default class JSONHeader {
    constructor(location, callback) {
        loadAtlasStructure(location);

        function loadAtlasStructure(location, callback) {
            jQuery.ajax({
                dataType: "json",
                url: location,
                async: true,
                success: function (files) {
                    files.map((file) => {
                        jQuery.ajax({
                            dataType: "json",
                            url: location + file,
                            async: true,
                            success: function (data) {
                                console.info(data);
                                if (!window.IndexAtlas) {
                                    window.IndexAtlas = new Atlas();
                                }
                                window.IndexAtlas.addSubAtlas(data);
                                console.info('JSONHeader::window.IndexAtlas', window.IndexAtlas);
                                callback();
                            }
                        });
                    })
                }
            })
        }
    }
}

В вашем ReactJS вы просто создаете обратный вызов и передаете его при вызове JSONHeader:

import React, {Component} from 'react';
import BrowserRouter from "react-router-dom/es/BrowserRouter";
import Switch from "react-router-dom/es/Switch";
import Route from "react-router-dom/es/Route";
import Redirect from "react-router-dom/es/Redirect";
import ScenePage from "../ScenePage/index";
import CoverPage from "../CoverPage/index";
import {INDEX, SCENE_PAGE} from "../../constantRoutes";
import JSONHeader from "../../newModel14Junio/JSONHeader";

export default class App extends Component {
    constructor(props) {
        super(props);

        const finishCallback = () => {
            this.setState({isAtlasLoading: false});
        };

        const header = new JSONHeader('/atlas/json/', finishCallback);

        this.state = {
            isAtlasLoading: true
        };        
    }

    render() {
        if (this.state.isAtlasLoading) {
            return (<div>Atlas loading</div>);
        }
        return (
            <BrowserRouter>
                <div>
                    <Switch>
                        <Route exact path = {INDEX} component = {CoverPage}/>
                        <Route path = {SCENE_PAGE} component = {() => <ScenePage IndexAtlas = {window.IndexAtlas}/>}/>
                        <Redirect from = "*" to = {INDEX}/>
                    </Switch>
                </div>
            </BrowserRouter>
        );
    }
}

Я надеюсь, что помог тебе.

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