我正在使用axios
与服务器进行communicate
。我想在用户请求服务器时显示加载器,并在请求完成时隐藏加载器
所以我做了一个自定义组件来执行这个任务,但是当我多次单击同一个按钮时,我的UI挂起
const Loader = () => {
const { loadingCount } = useLoadingState(),
{showLoading, hideLoading} = useLoadingActions();
useEffect(()=>{
const self = this
axios.interceptors.request.use(function (config) {
showLoading();
return config
}, function (error) {
return Promise.reject(error);
});
axios.interceptors.response.use(function (response) {
// spinning hide
// self.props.loading(false)
hideLoading()
return response;
}, function (error) {
hideLoading();
return Promise.reject(error);
});
})
return (
<div>
{loadingCount > 0 ?<div style={{position:"fixed",display:"flex",justifyContent:"center",alignItems:"center",width:'100%',height:'100%',zIndex:999999}}>
{/*{loadingCount > 0 ? */}
<Spin tip="Loading..." style={{zIndex:999999}}></Spin>
{/*: null}*/}
</div>: null}
</div>
);
};
问题出在useeffect
当我注释掉useEffect代码时,它工作得很好。
NoTe:显示加载和隐藏加载增加和减少加载计数。
我想我已经在卸载组件时释放了 axios 对象???
将空数组添加到 sencod 参数以useEffect
.
它的工作方式类似于功能组件中的componentDidMount()
。
const { useState, useEffect } = React;
const Counter = () => {
const [count, setCount] = useState(0)
const [isLoaded, setIsLoaded] = useState(false);
useEffect(() => {
setTimeout(() => {
setIsLoaded(true);
}, 3000);
}, []); // here
return (
<div>
{
isLoaded &&
<div>
<p>You clicked {count} times</p>
<button onClick={() => setCount(count + 1)}>
Click me
</button>
</div>
}
</div>
)
}
ReactDOM.render(<Counter />, document.getElementById('app'))
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.7.0-alpha.2/umd/react.development.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.7.0-alpha.2/umd/react-dom.production.min.js"></script>
<div id="app"></div>
我通常使用此代码来显示请求数据正在处理时的加载,并在完成后隐藏
const Loader = () => {
const {data, setdata} = useState([])
useEffect(()=>{
axios.get('your host').then(res => {
setdata(res.data);
}).catch(err => {
setdata(res.data);
}
});
return (
<div>
{data.length > 0
?
<div style={{position:"fixed",display:"flex",justifyContent:"center",alignItems:"center",width:'100%',height:'100%',zIndex:999999}}> </div>
:
<Spin tip="Loading..." style= {{zIndex:999999}}>
</Spin>
</div>
);
};
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.6.3/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.6.3/umd/react-dom.production.min.js"></script>
首先,我在共享文件夹中创建了加载组件。我正在使用Daisy UI,这就是为什么你必须首先安装tailwind & daisy,否则它将无法工作。我的加载代码:
import React from 'react';
const Loading = () => {
return (
<div className="flex items-center justify-center ">
<div className="w-16 h-16 border-b-2 border-gray-900 rounded-full animate-spin"></div>
</div>
);
};
export default Loading;
然后我在我的 Allproduct 组件中使用此加载组件。为了查看加载,我创建了重新加载使用状态.您将在我的代码中看到下面,这将有助于我的加载器在获取时间很长时显示。
import React, { useEffect, useState } from 'react';
import Loading from '../Shared/Loading';
import AllProduct from './AllProduct';
const AllProducts = () => {
const [products, setProduct]=useState([])
const [Reload, setReload] = useState(true);
useEffect(()=>{
fetch('https://stormy-hamlet-97462.herokuapp.com/products/')
.then(res=>res.json())
.then(data=>{setProduct(data)
setReload(false)})
},[])
if(Reload){
return <Loading></Loading>
}
return (
<div>
<h4 className='text-4xl text-primary text-center sm:w-full px-32 mx-5
lg:my-12 '>All Products</h4>
<div className='grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-5'>
{
products.map(product=><AllProduct key={product._id} product={product} ></AllProduct>)
}
</div>
</div>
);
};
export default AllProducts;