繁体   English   中英

使用来自 API 的数据初始化 Next.js webapp 并将其添加到 state 的最佳实践是什么?

[英]What are the best practices to initialize a Next.js webapp with data from an API and adding it to the state?

我正在使用 Zusand 进行 state 管理(尽管我想同样的原则适用于所有 state 管理库,例如 Redux 或 Recoil)。 我想过并尝试过:

  1. 在第一页渲染期间使用getStaticProps()获取数据并使用useEffect()将数据推送到 state。 问题是在加载特定页面之前,数据不会推送到 state。 我不想使用getInitialProps() ,因为它已被弃用。
  2. 一个有效的解决方案(虽然不确定它是否是最佳实践)是在应用程序首次初始化时在_app.js上使用 SWR 来获取 API 数据,并使用useEffect()将数据推送到 state 。 这样,我可以使用 state 中的数据自由填充页面,并且只需要一次 API 调用。 下面的例子:
function MyApp({ Component, pageProps }) {
  
  // Load data from api with SWR
  const fetcher = (url) => fetch(url).then((res) => res.json());
  const { data, error } = useSWR(
    "https://example.com/api",
    fetcher
  );

  // Get data setter from state
  const setData = useStore((state) => state.setData);

  // When data is fetched successfully, populate state with data
  useEffect(() => {
    if (data) {
      setData(data);
    }
  }, [data]);

  if (error) return "Error has occured";
  if (!data) return "Loading...";

  return (
    <Layout>
      <Component {...pageProps} />
    </Layout>
  );
}

export default MyApp;

有没有更好的方法来获取数据并在第一次加载应用程序时使用它来填充 state? 最佳实践是什么?

我使用 Zusstand 上下文提供程序以正确的方式工作,并使用 Nextjs pagePropsgetStaticProps()对其进行初始化。

_app.js

function MyApp({ Component, pageProps }) {
  const createStore = initStore(pageProps.initZustand);
  return (
    <Provider createStore={createStore}>
      <Component {...pageProps} />
    </Provider>
  );
}

export default MyApp;

store.js

export const { Provider, useStore } = createContext();

let store = {
  names: ["Name 1", "Name 2", "Name 3"],
  random: [],
  setRandom: (data) => {
    set((state) => ({ random: data }));
  },
};

export const initStore = (data) => {
  const createStore = () =>
    create(
      devtools((set, get) => ({
        ...store,
        ...data,
      }))
    );

  return createStore;
};

index.js 获取静态属性:

export async function getStaticProps(context) {
  const res = await fetch("https://jsonplaceholder.typicode.com/users");
  const posts = await res.json();

  return {
    props: {
      initZustand: {
        posts: posts,
      },
    },
  };
}

暂无
暂无

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

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