【问题标题】:Next.js Fetch and Maintain global data for all componentsNext.js 获取和维护所有组件的全局数据
【发布时间】:2020-10-14 19:20:06
【问题描述】:

在我的 Next.js 应用程序中,我需要进行一个 API 调用,该调用将返回一个 JSON 响应,所有组件都需要使用该响应。因此,我将避免在我的组件中多次调用同一个 API。实现这一目标的正确方法是什么?

【问题讨论】:

  • 请添加更多上下文,包括一些代码。这很难回答,因为它非常广泛
  • @ArnaudClaudel 感谢您的友好回复。我需要一些帮助来维护从 API 调用中获取的所有组件的全局数据

标签: reactjs next.js react-component


【解决方案1】:

取决于应用的范围。
如果它很大,你可能应该采用像 Redux 这样的状态管理器,正如 Moshin Amjad 所说。

如果它是一个较小的应用程序,您可以尝试使用 React 上下文 API 来管理它。
我将以最简单的方式举一个例子,使用功能组件,利用getStaticProps 而不是getInitialProps 来获取静态生成的页面。

开始创建一个简单的上下文

libs/context.js

import React from "react";
export const Context = React.createContext();

然后使用来自 getStaticProps(或 getInitialProps)的数据填充 useState 挂钩(或者更好的是,useReducer 取决于数据的结构),然后将其传递给上下文提供程序。

pages/index.js

import React from 'react'
import { Context } from "../libs/context.js"

import Title from "../components/Title"
import Button from "../components/Button"

// data will be populated at build time by getStaticProps()

function Page({ data }) {
    const [ context, setContext ] = React.useState(data)
    return (
        <Context.Provider value={[context, setContext]}>
            <main>
                <Title />
                <Button />
            </main>
        </Context.Provider>
    )
}

export async function getStaticProps(context) {

  // fetch data here
  const data = await fetchData()

  // Let's assume something silly like this:
  // {
  //     buttonLabel: 'Click me to change the title',
  //     pageTitle: 'My page'
  // }
  
  return {
    props: {
       data
    }, // will be passed to the page component as props
  }
}

最后在提供者的任何孩子中使用它(或改变它!)。

components/Title.js

import React, { useContext } from "react"
import { Context } from "./Context"

export default function MyComponent() {
   const [context, setContext] = useContext(Context)
   
   return (
       <h1>{context.pageTitle}</h1>
   )
}

components/Button.js

import React, { useContext } from "react"
import { Context } from "./Context"

export default function MyComponent() {
   const [context, setContext] = useContext(Context)
   
   function changeTitle() {
      preventDefault();
      setContext(oldContext => ({ 
          ...oldContext, 
          pageTitle: 'New page title!' 
      }))
   }

   return (
       <div>
          <button onClick={changeTitle}>{context.buttonLabel}</button>
       </div>
   )
}

它未经测试,但你明白了。
最终,您可以将上下文提供程序移动到高阶组件中以包装每个页面,如果您需要更高级别的数据,甚至可以在 pages/_app.js 中。

请记住,如果应用程序扩展,您应该考虑使用 Redux 之类的东西。

【讨论】:

  • 不错的方法,有人可以测试一下并确认它有效吗?
  • 嗨 Stefano,我们可以将数据从 server.js 传递到 _app.js 或页面组件吗?
【解决方案2】:

使用 redux 将您的状态存储在全局存储中,以便多个组件可以访问它,这是您的用例类型的常见模式。 还有下一个包装器 这是链接next-redux-wrapperredux

【讨论】:

    猜你喜欢
    • 2018-08-24
    • 1970-01-01
    • 2016-07-11
    • 1970-01-01
    • 2015-12-08
    • 2020-10-25
    • 2018-01-22
    • 2021-12-09
    相关资源
    最近更新 更多