反应useEffect并返回渲染

时间:2020-01-07 22:23:21

标签: reactjs react-hooks

我有一个带有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>
);

3 个答案:

答案 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,而不是一个空数组。如果postsnull,则什么也不渲染(或微调)。这样可以防止在进行数据提取时闪烁“无帖子”。

答案 2 :(得分:0)

您将LiveData用作useEffect,因为您提供了一个空数组作为依赖项。顾名思义,它是在组件首次渲染后调用的。

因此,要回答您的问题,不,您不能在首次渲染时就渲染获取结果。您可以使用componentDidMount组件来改善UX,然后等到获取数据为止。

或者您可以在父组件中获取数据并将其作为prop传递下来,这样您就可以首先使用获取的数据进行渲染。