【问题标题】:Passing Async State to Next.js Component via Prop通过 Prop 将异步状态传递给 Next.js 组件
【发布时间】:2022-01-20 19:24:32
【问题描述】:

我正在通过 getStaticProps() 异步获取 WordPress 帖子...

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

...并将它们传递给useState:

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

然后,我将状态传递给组件:

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

这是必要的,因为另一个组件将setFilteredArticles 具有过滤功能。

但是当我们将状态传递给ArticlesGrid 时,组件加载时数据还没有准备好。这让我很困惑,因为我们在 router.isFallback 条件内传递状态。

即使我们在useEffect...内设置状态...

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

...对于组件来说,数据到达太晚了。

我是 Next.js 的新手。我可能可以破解这个问题,但我认为有一个优雅的解决方案。

【问题讨论】:

    标签: javascript reactjs asynchronous next.js use-state


    【解决方案1】:

    让我们看一些useEffect 的例子:

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

    这个useEffect第一次渲染之后以及随后的每次重新渲染时执行。

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

    useEffect 只执行一次,在第一次渲染之后

    useEffect(() => {
      console.log("Hello there when id changes");
    }, [props.id]);
    

    这个useEffect第一次渲染之后执行,每次props.id改变。

    您的问题的一些可能解决方案:

    无文章案例

    您可能希望在您的 ArticleGrid 组件中处理这种情况,以防止任何潜在的错误。

    在 ArticleGrid.js 中:

    const {myArticles} = props;
    
    if(!myArticles) {
        return (<div>Your custom no data component... </div>);
    }
    
    // normal logic
    return ...
    

    或者,您也可以在父组件中处理这种情况:

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

    使用初始道具

    在未设置过滤器的情况下发送初始道具:

    const myArticles = filteredArticles || posts?.edges;
    

    然后:

    <ArticleGrid myArticles={myArticles} />
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2019-11-16
      • 2019-07-14
      • 2021-07-28
      • 1970-01-01
      • 1970-01-01
      • 2017-12-30
      • 2018-09-29
      • 1970-01-01
      相关资源
      最近更新 更多