我想知道如何在React中渲染之前正确加载数据。
我有一个应用程序,从API获取有关星星大战角色的数据,并将其呈现在页面上。我还想获取下一个角色的数据,然后我想通过点击按钮呈现它。我有一个这个应用程序的例子:
'
function fetchData(count, setState) {
fetch("https://swapi.dev/api/people/" + count)
.then(res => res.json())
.then(data => setState({
id: count,
name: data.name,
birth_year: data.birth_year,
gender: data.gender
}))
}
function App() {
let [data, setData] = React.useState({});
let [preloadedData, setPreloadedData] = React.useState({});
let [count, setCount] = React.useState(1);
React.useEffect(() => {
if (count === 1) {
fetchData(count, setData)
fetchData(count + 1, setPreloadedData);
}
else {
setData(preloadedData)
fetchData(count + 1, setPreloadedData);
}
}, [count]);
console.log(count)
return (
<main>
<h1>Starwars character data</h1>
<p><span>Number:</span> {data.id}</p>
<p><span>Name:</span> {data.name}</p>
<p><span>Birth year:</span> {data.birth_year}</p>
<p><span>Gender:</span> {data.gender}</p>
<button onClick={() => setCount(count + 1)}>Next character</button>
</main>
)
}
'
我有两个问题:1)这是解决我的问题的正确方法吗,或者可以有更好的实践?2)我想这种方法仍然可能更好,因为console.log被调用了3次,所以我的组件在每次计数状态改变时呈现3次,而且可能更少?
想知道你的意见
2条答案
按热度按时间sbdsn5lh1#
1)这是解决我问题的正确方法吗
它似乎起作用了,这已经是一个可以接受的解决方案。
当然,它有一些限制,但根据您的实际需求,您可能会暴露他们。特别是,如果用户快速点击几次"下一个字符"按钮(在接收下一个数据之前),您可能会取消同步
count
和data
,如果几个创建的获取请求给出无序的响应,preloadedData
也可能不反映count + 1
。2)我想这种方式仍然可以更好,因为console.log被调用了3次,所以我的组件在每次计数状态改变时呈现3次,它可以更少?
您不必担心重新呈现(从组件函数被重新执行的意义上说):React更新它的虚拟DOM,但是如果它在输出中没有看到任何变化,那么它就不会触及真正的DOM(因此几乎没有UI影响)。
在您的情况下:
count
递增,但模板不受影响=〉无DOM更改data
已更改,这会影响模板值=〉DOM已修改preloadedData
更新,不影响模板=〉无DOM变更是否可以有更好的做法?
我们总是可以改进我们的代码!
在您的情况下,您可以解决上面提到的限制,同时潜在地提供启用"前一个字符"导航的额外特性,同时仍然重用预加载的数据。
为此,我们需要累积预加载的数据及其关联的
id
(count
),例如,使用react-useuseList
钩子:nimxete22#
如果您不希望useEffect执行3次,可以传递一个空数组,这样它将只在安装和卸载组件时执行,如下所示:
在useEffect中获取数据是不错的,但是对于复杂的应用程序来说,使用Redux并用Thunk获取数据要好得多。另一个好的做法是在useEffect结束时返回回调函数来清理数据,如下所示:
我不知道它是否回答了你的问题,但我希望它能有所帮助