我有一个巨大的组件,它呈现的时间足够长,如果它经常发生,用户会注意到。它的内容是异步加载的(从服务器)每当函数"getData"更改,在等待期间显示加载器。
我试图写一个代码,这将呈现组件只有2次时,功能的变化-第一次显示加载和第二次显示数据。使用标准的useEffect
会导致它被渲染3次,第一次不会改变任何对用户可见的内容。
type tData = /*some type*/
const Component = (props: {getData: () => Promise<tData[]>}) => {
const {getData} = props;
const [loader, setLoader] = useState(true);
const [data, setData] = useState<tData[]>([]);
useEffect(() => {
setLoader(true);
setData([]);
getData().then((newData) => {
setData(newData);
setLoader(false);
});
}, [getData, setLoader, setData]);
// ... the rest of the component (that doesn't use the function getData)
};
三个渲染是:
getData
已经改变-效果运行和改变状态,但有0变化可见的用户(这是我想摆脱的渲染)loader
已更改为true
和data
已更改为[]
-一个有用的渲染,实际上改变了UIloader
已更改为false
和data
已更改为一个新的值-一个有用的渲染,实际上改变了UI
我怎么能修改这段代码,不有一个贫瘠的渲染时,getData
的变化?
这是一个非常常见的用例。您可以在useEffect()中使用if()。使用.then()会使事情变得复杂。使用async await使其异步。
useEffect(() => {
async function loadData() {
const res = getData()
return res
}
let data = await loadData()
//check if it's undefined
if (data && data!=='init') {
setStateData(data)
}
}, [])
这就是我如何实现这样的东西。然而,看起来数据获取对你来说有点复杂,但本质上,永远不要同步获取数据,除非你绝对有必要,并检查是否在useEffect中未定义设置状态变量,以便它只设置一次。