【问题标题】:How can I pass setState function between contextProvider?如何在 contextProvider 之间传递 setState 函数?
【发布时间】:2021-05-04 10:33:12
【问题描述】:

在为其他元素重新传递上下文提供程序时,我在设置状态时遇到了一些问题,这是我的代码。 我正在创建一个 FancyboxContext 以备不时之需,我可以在任何地方调用它。

import React, { createContext, useContext, useState } from 'react';

interface FancyboxContextInterface {
  fancybox: boolean;
  setFancybox(value: boolean): void;
}

interface FancyboxProviderProps {
  children: React.ReactNode;
}

interface UseFancyboxInterface {
  fancybox: boolean;
  setFancybox: React.Dispatch<React.SetStateAction<boolean>>;
}

const FancyboxInitialState = {
  fancybox: false,
  setFancybox: () => {}
};

const FancyboxContext = createContext<FancyboxContextInterface>(
  FancyboxInitialState
);

const FancyboxProvider: React.FC<FancyboxProviderProps> = ({
  children
}: FancyboxProviderProps) => {
  const [fancybox, setFancybox] = useState(FancyboxInitialState.fancybox);

  return (
    <FancyboxContext.Provider
      value={{
        fancybox,
        setFancybox
      }}
    >
      {children}
    </FancyboxContext.Provider>
  );
};

export const useFancybox = (): UseFancyboxInterface => {
  const context = useContext(FancyboxContext);
  const { fancybox, setFancybox } = context;

  return {
    fancybox,
    setFancybox
  };
};

export default FancyboxProvider;

在ContextProvider中涉及到_document.tsx;

...
    render(): JSX.Element {
        return (
          <Html lang="pt">
            <Head>
              <link
                rel="stylesheet"
                href="https://fonts.googleapis.com/css2?family=Roboto:wght@300;400;700&display=swap"
              />
            </Head>
            <body>
              <FancyboxProvider>
                <Main />
              </FancyboxProvider>
              <NextScript />
            </body>
          </Html>
        );
      }

但是当我尝试开始对 setState() 的简单调用时,没有任何反应

import React, { useEffect } from 'react';
import { AppProps } from 'next/app';
import { useFancybox } from '../hooks/useFancybox';

import { Fancybox, GlobalStyles } from '../styles/global';

const myApp: React.FC<AppProps> = ({ Component, pageProps }) => {
  const { fancybox, setFancybox } = useFancybox();

  useEffect(() => setFancybox(true), []);

  return (
    <>
      {fancybox ? <Fancybox /> : ''}
      <Component {...pageProps} />
      <GlobalStyles />
    </>
  );
};

export default myApp;

【问题讨论】:

    标签: reactjs typescript react-hooks next.js


    【解决方案1】:

    首先,你应该知道 React Context 只能在客户端使用。

    您不能放置 ContextProvider in _document.js,因为它只在服务器端运行。在您的 _app.js 中,您正在导出 javascript 函数 myApp 而不是 React 组件 MyApp

    您可以做的是将您的 FancyProvider 放在 _app.js 并在任何页面中调用您的 setState

    你的_app.js 应该是什么样子

    import React from "react";
    import { AppProps } from "next/app";
    import { GlobalStyles } from "../styles/global";
    
    const MyApp: React.FC<AppProps> = ({ Component, pageProps }) => {
      return (
        <FancyboxProvider>
          <Component {...pageProps} />
          <GlobalStyles />
        </FancyboxProvider>
      );
    };
    
    export default MyApp;
    

    现在您可以在 /pages/index.js or any other page 上调用您的 setState

    import { useEffect } from "react";
    import { useFancybox } from "../hooks/useFancybox";
    import { Fancybox } from "../styles/global";
    
    export default function Home() {
      const { fancybox, setFancybox } = useFancybox();
    
      useEffect(() => {
        setFancybox(true);
      }, []);
    
      return (
        <div>
          {fancybox ? <Fancybox /> : ""}
        </div>
      );
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-09-26
      • 1970-01-01
      • 1970-01-01
      • 2019-06-04
      • 1970-01-01
      相关资源
      最近更新 更多