简体   繁体   English

通过 Prop 将异步 State 传递给 Next.js 组件

[英]Passing Async State to Next.js Component via Prop

I'm fetching WordPress posts asynchronously via getStaticProps() ...我正在通过getStaticProps()异步获取 WordPress 帖子...

export async function getStaticProps({ params, preview = false, previewData }) {
    const data = await getPostsByCategory(params.slug, preview, previewData)
    return {
        props: {
            preview,
            posts: data?.posts
        },
    }
}

... and passing them to useState : ...并将它们传递给useState

const [filteredArticles, setFilteredArticles] = useState(posts?.edges)

Then, I pass the state to a component:然后,我将 state 传递给一个组件:

router.isFallback ? (
    // If we're still fetching data...
    <div>Loading…</div>
) : (
    <ArticleGrid myArticles={filteredArticles} />

This is necessary because another component will setFilteredArticles with a filter function.这是必要的,因为另一个组件将使用过滤器setFilteredArticles设置FilteredArticles。

But when we are passing the state to ArticlesGrid , the data is not ready when the component loads.但是当我们将 state 传递给ArticlesGrid时,组件加载时数据还没有准备好。 This is confusing to me since we passing the state within a router.isFallback condition.这让我很困惑,因为我们在router.isFallback条件下传递了 state。

Even if we set state within useEffect ...即使我们将 state 设置在useEffect ...

const [filteredArticles, setFilteredArticles] = useState()
useEffect(() => {
    setFilteredArticles(posts)
}, [posts?.edges])

... the data arrives too late for the component. ...对于组件而言,数据到达太晚了。

I'm new to Next.js.我是 Next.js 的新手。 I can probably hack my way through this, but I assume there's an elegant solution.我可能可以解决这个问题,但我认为有一个优雅的解决方案。

Let's look at some useEffect examples:让我们看一些useEffect示例:

useEffect(() => {
  console.log("Hello there");
});

This useEffect is executed after the first render and on each subsequent rerender.useEffect在第一次渲染之后和每次后续重新渲染时执行。

useEffect(() => {
  console.log("Hello there once");
}, []);

This useEffect is executed only once, after the first render .这个useEffect只执行一次,在第一次 render 之后

Some possible solutions to your problem:您的问题的一些可能的解决方案:

No articles case无文章案例

You probably want to treat this case in your ArticleGrid component anyway, in order to prevent any potential errors.无论如何,您可能希望在您的 ArticleGrid 组件中处理这种情况,以防止任何潜在的错误。

In ArticleGrid.js:在 ArticleGrid.js 中:

const {myArticles} = props;

if(!myArticles) {
    return (<div>Your custom no data component... </div>);
}

// normal logic
return ...

Alternatively, you could also treat this case in the parent component:或者,您也可以在父组件中处理这种情况:

{
  router.isFallback ? (
    // If we're still fetching data...
    <div>Loading…</div>
  ) : (
    <>
      {
        filteredArticles
          ? <ArticleGrid myArticles={filteredArticles} />
          : <div>Your custom no data component... </div>
      }
    </>
  )
}

Use initial props使用初始道具

Send the initial props in case the filteres haven't been set:在未设置过滤器的情况下发送初始道具:

const myArticles = filteredArticles || posts?.edges;

and then:接着:

<ArticleGrid myArticles={myArticles} />

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM