在我的Next.js应用中,我需要进行API调用,并返回JSON响应以供所有组件使用。因此,我将避免在组件中对同一API进行多次调用。有什么正确的方法来实现这一点?
根据应用程序的范围而定。
如果是较大的应用程序,建议像Moshin Amjad所说的那样采用状态管理器Redux。
如果是较小的应用程序,则可以尝试使用React上下文API来管理它。
我将用最简单的方式创建一个示例,使用函数组件,利用getStaticProps
而不是getInitialProps
来获取静态生成的页面。
开始创建一个简单的上下文
libs/context.js
import React from "react";
export const Context = React.createContext();
然后使用useState
hook(或更好的是,根据数据结构使用useReducer
)将从getStaticProps(或getInitialProps)获取的数据填充到其中,并将其传递给上下文提供程序。
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>
)
}
组件/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之类的东西。
server.js
传递到 _app.js
或页面组件中? - avocado