使用 fetch API 时在 AJAX 调用期间显示微调器
Display spinner during AJAX call when using fetch API
在我的项目中,我正在迁移到 React,因此不会加载 JQuery。因为我不再有 JQuery,所以对于 AJAX 调用我正在使用 fetch。使用 JQuery 我可以挂钩 AJAX 调用的开始和结束,因此很容易将光标更改为微调器。我在 fetch 中找不到类似的钩子。除了在每个 AJAX 调用中更改它之外,还有其他方法可以做到这一点吗?
很多谷歌搜索一直在寻找关于...的答案。JQuery。
fetch in thenable,可以在then()中添加spinner stop函数,在收到响应后调用。并将其包装在另一个函数中用于 headers 和挂钩。
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
});
当 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>
);
}
}
好了,我认为代码很容易理解:
// 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/
我发现使用手动设置的主要问题是 "loading" 标志
true / false 是很容易错误地跳过设置为 false 标志并且你的应用程序会被绞死),另一方面我不想在并行调用多个 ajax 请求时搞砸,当您想跟踪其中一些请求时,这会变得更加困难,但在其他情况下,您想要发出静默请求。
我创建了一个名为 react-promise-tracker 的微库来以更自动的方式处理这个问题。工作原理
安装承诺跟踪器
npm install react-promise-tracker --save
实现一个简单的加载指示器组件(你可以为它添加你需要的样式),并用 promiseTrackerHoc
包装它
import { promiseTrackerHoc } from 'react-promise-tracker';
const InnerLoadingIndicator = props => (
props.trackedPromiseInProgress &&
<h1>Hey some async call in progress ! Add your styling here</h1>
);
export const LoadingIndicator = promiseTrackerHoc(InnerLoadingIndicator);
在您的应用程序根组件中实例化它:
render(
<div>
<App />
<LoadingIndicator/>
</div>,
document.getElementById("root")
);
每当你想跟踪一个获取或任何基于承诺的调用(包括async/await),只需用react-promise-tracker函数包装它trackPromise:
import { trackPromise } from 'react-promise-tracker';
export class MyComponent extends Component {
componentWillMount() {
trackPromise(
userAPI.fetchUsers()
.then((users) => {
this.setState({
users,
})
})
);
}
// ...
}
更多资源:
- 分步教程(包括添加一个漂亮的微调器):https://www.basefactor.com/react-how-to-display-a-loading-indicator-on-fetch-calls
在我的项目中,我正在迁移到 React,因此不会加载 JQuery。因为我不再有 JQuery,所以对于 AJAX 调用我正在使用 fetch。使用 JQuery 我可以挂钩 AJAX 调用的开始和结束,因此很容易将光标更改为微调器。我在 fetch 中找不到类似的钩子。除了在每个 AJAX 调用中更改它之外,还有其他方法可以做到这一点吗?
很多谷歌搜索一直在寻找关于...的答案。JQuery。
fetch in thenable,可以在then()中添加spinner stop函数,在收到响应后调用。并将其包装在另一个函数中用于 headers 和挂钩。
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
});
当 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>
);
}
}
好了,我认为代码很容易理解:
// 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/
我发现使用手动设置的主要问题是 "loading" 标志 true / false 是很容易错误地跳过设置为 false 标志并且你的应用程序会被绞死),另一方面我不想在并行调用多个 ajax 请求时搞砸,当您想跟踪其中一些请求时,这会变得更加困难,但在其他情况下,您想要发出静默请求。
我创建了一个名为 react-promise-tracker 的微库来以更自动的方式处理这个问题。工作原理
安装承诺跟踪器
npm install react-promise-tracker --save
实现一个简单的加载指示器组件(你可以为它添加你需要的样式),并用 promiseTrackerHoc
包装它import { promiseTrackerHoc } from 'react-promise-tracker';
const InnerLoadingIndicator = props => (
props.trackedPromiseInProgress &&
<h1>Hey some async call in progress ! Add your styling here</h1>
);
export const LoadingIndicator = promiseTrackerHoc(InnerLoadingIndicator);
在您的应用程序根组件中实例化它:
render(
<div>
<App />
<LoadingIndicator/>
</div>,
document.getElementById("root")
);
每当你想跟踪一个获取或任何基于承诺的调用(包括async/await),只需用react-promise-tracker函数包装它trackPromise:
import { trackPromise } from 'react-promise-tracker';
export class MyComponent extends Component {
componentWillMount() {
trackPromise(
userAPI.fetchUsers()
.then((users) => {
this.setState({
users,
})
})
);
}
// ...
}
更多资源: - 分步教程(包括添加一个漂亮的微调器):https://www.basefactor.com/react-how-to-display-a-loading-indicator-on-fetch-calls