Отображение spinner во время вызова AJAX при использовании fetch API


В моем проекте я мигрирую в React и поэтому не загружаю JQuery. Поскольку у меня больше нет JQuery, для вызовов AJAX я использую fetch. С помощью JQuery я могу зацепить начало и конец вызовов AJAX, поэтому очень легко изменить курсор на счетчик. Я не могу найти подобные крючки в fetch. Есть ли способ сделать это, кроме изменения его в каждом отдельном вызове AJAX?

Множество Гуглов просто продолжали находить ответы... На jQuery.

3 2

3 ответа:

Ну вот, я думаю, что код в значительной степени самоочевиден:

// Store a copy of the fetch function
var _oldFetch = fetch; 

// Create our new version of the fetch function
window.fetch = function(){

    // Create hooks
    var fetchStart = new Event( 'fetchStart', { 'view': document, 'bubbles': true, 'cancelable': false } );
    var fetchEnd = new Event( 'fetchEnd', { 'view': document, 'bubbles': true, 'cancelable': false } );

    // Pass the supplied arguments to the real fetch function
    var fetchCall = _oldFetch.apply(this, arguments);

    // Trigger the fetchStart event
    document.dispatchEvent(fetchStart);

    fetchCall.then(function(){
        // Trigger the fetchEnd event
        document.dispatchEvent(fetchEnd);
    }).catch(function(){
        // Trigger the fetchEnd event
        document.dispatchEvent(fetchEnd);
    });

    return fetchCall;
};

document.addEventListener('fetchStart', function() {
    console.log("Show spinner");
});

document.addEventListener('fetchEnd', function() {
    console.log("Hide spinner");
});

Вот живой пример: https://jsfiddle.net/4fxfcp7g/4/

Что вы можете сделать, когда fetch первоначально происходит, вы setState к загрузке как true. Затем, как только выборка сделана, вы можете setState как загрузка false. И вы показываете счетчик, основанный на текущем состоянии.

Например,

class SomeComponent extends React.Component {
  constructor(props) {
    super(props);
    this.state = { loading: false };
  }

  loadData(e) {
    e.preventDefault();
    this.setState({ loading: true });
    fetch(....).then( res => res.json()).then( resJson => {
      // do other stuff here.
      this.setState({ loading: false });    
    });
  }

  render() {
    return (
      <div>
         <DisplayComponent />
         <button onClick={this.loadData}>Click Me</button>
         { this.state.loading ? <Spinner /> : null }
      </div>
    );
  }
}

Вы можете проверить react условный рендеринг

Fetch in thenable, вы можете добавить функцию spinner stop в then (), которая вызывается после получения ответа. И оберните его в другую функцию для заголовков и зацепления.

function ajax(someUrl, method) {
    var myHeaders = new Headers();

    var myInit = { 
        method: method,
        headers: myHeaders
    };
    showSpinner();

    return fetch(someUrl, myInit).then(function(response) {
        //... do some with response
        hideSpinner();

        return response;
    }).catch(function(error) {
        //... tell the user the request failed and hide the spinner
        hideSpinner();

        return error;
    });
}

ajax('example.com').then(function(response) {
    // ...
}).catch(function(error) {
    // show error
});