我有一个带有fetch的useEffect,我想先渲染它,因为它先运行else案例,然后再运行useEffect。查看页面时显示其他情况,然后显示帖子。有没有一种方法可以先呈现useEffect?
const [posts, setPosts] = useState([]);
useEffect(() => {
const data = await fetch('https://localhost:1111/api/posts', {
credentials: 'include'
});
const response = await data.json();
setPosts(response);
}, []);
return (
<div>
{posts.length > 0 ? (
posts.map(post => (
<Post key={post.id} onUpdate={() => handleUpdate()} post={post} />
))
) : (
<p>No posts</p>
)}
</div>
);
答案 0 :(得分:2)
您可以获得该结果,但是您需要以其他方式进行。
首次渲染组件时,整个函数将运行,然后根据函数返回的内容更新页面。这或多或少是同步发生的。只有渲染后,效果才会运行。不可能更改此顺序:渲染始终在第一,效果始终在渲染之后。
因此,如果您不希望在此效果完成之前不显示任何内容,则需要从渲染中返回null。然后,在获取完成后,您将更新状态,这将使其再次呈现,这次不使用null。
例如,在这里,我采用了您的代码并添加了另一种可能性:状态可能为null。我正在使用它来指示它尚未加载。稍后,一旦获取了数据,状态就会更新,并且组件会重新呈现。
const [posts, setPosts] = useState(null);
useEffect(() => {
(async () => {
const data = await fetch('https://localhost:1111/api/posts', {
credentials: 'include'
});
const response = await data.json();
setPosts(response);
})();
}, []);
if (posts === null) {
return null;
}
return (
<div>
{posts.length > 0 ? (
posts.map(post => (
<Post key={post.id} onUpdate={() => handleUpdate()} post={post} />
))
) : (
<p>No posts</p>
)}
</div>
);
答案 1 :(得分:0)
您可以将帖子默认设置为null
,而不是一个空数组。如果posts
为null
,则什么也不渲染(或微调)。这样可以防止在进行数据提取时闪烁“无帖子”。
答案 2 :(得分:0)
您将LiveData
用作useEffect
,因为您提供了一个空数组作为依赖项。顾名思义,它是在组件首次渲染后调用的。
因此,要回答您的问题,不,您不能在首次渲染时就渲染获取结果。您可以使用componentDidMount
组件来改善UX,然后等到获取数据为止。
或者您可以在父组件中获取数据并将其作为prop传递下来,这样您就可以首先使用获取的数据进行渲染。