reactjs 带有React上下文的最小样板确认模式

7vhp5slm  于 2023-10-17  发布在  React
关注(0)|答案(2)|浏览(86)

我试图在React中理解Context的概念,我想用它来创建一个可重用的确认模态,在我看来,它具有最小的样板(对于模态消费者),由于我对上下文如何工作的误解(如useState),这是我的想象:
从主应用程序中,导入组件和启动器函数:

import {ConfirmDialog, ShowConfirmModal} from './components/ConfirmDialog';

在components/ConfirmDialog.js中,您可以:

import React, {createContext, useContext} from "react";
import {ModalDialog, Text} from "@forge/react";

const context = createContext({ isOpen: false })

export const ConfirmDialog = () => {

    const _context = useContext(context)

    return _context.isOpen && <ModalDialog header={_context.title} onClose={_context.onClose} closeButtonText='Confirm'>

        <Text>{_context.message}</Text>

    </ModalDialog>

}

export const ShowConfirmModal = (title, message, onClose) => {

    const [_context, _setContext] = useContext(context)

    _setContext({
        message, title, onClose, isOpen: true
    })

}

这将允许使用者将组件添加到文档的根目录中,并通过调用ShowConfirmModal函数来显示它。但是,这不起作用,因为我不能用途:const [_context, _setContext] = useContext(context)现在我不明白什么是解决这个问题的最佳方法,即使我的方法是正确的(经过一些修改)。
我是React的新手,我想要的不仅仅是问题的解决方案,而是方向,我的推理正确吗?或者我不是“在React中思考”?(我是MVC开发者)

hlswsv35

hlswsv351#

首先,你需要一个Provider组件:

const DialogContext= createContext(undefined);

export const ConfirmDialogProvider = ({ children }) => {
  // declare your state here
  const [isOpen, setIsOpen] = useState(false);
  const [message, setMessage] = useState(undefined);

  return (
    <DialogContext.Provider value={{ isOpen, setIsOpen, message, setMessage }}>
      <>
        {children}
        <ModalDialog header={title} onClose={onClose} closeButtonText="Confirm">
          <Text>{message}</Text>
        </ModalDialog>
      </>
    </DialogContext.Provider>
  );
};

然后,您必须在所有想要打开模态的组件的祖先中使用您的提供程序,例如。

function App() {
  return (
    <ConfirmDialogProvider>
      <Other>
        <Components />
        <Here />
      </Other>
    </ConfirmDialogProvider>
  )
}

现在你可以使用你的上下文:

const SomeComponent = () => {
  const { setIsOpen, setMessage } = useContext(DialogContext);
  return (
    <button
      onClick={() => {
        setIsOpen(true);
        setMessage("Title");
      }}
    >
      Open modal
    </button>
  );
};

备注:

  • 您可以在一个单独的组件中声明您的模态,并在那里使用useContext(DialogContext),但无论如何都必须将其添加到树中
  • 您可以对状态进行分组,因此不必使用多个函数来更改状态
  • 您可以创建一个像const useDialogContext = useContext(DialogContext)这样的辅助钩子,这样就不必编写那么多代码
f0brbegy

f0brbegy2#

你的方法是正确的,但是关于React上下文如何工作的建议很少,你可以按照这些步骤进行一些更正
1.创建一个上下文挂钩,如下所示:默认值应该包括您在组件中访问的属性。
`

const ConfirmDialogContext = createContext({
      isOpen: false,
      title: "",
      message: "",
      onClose: () => {},
    });`

1.提供组件
提供程序设置上下文的值

export const ConfirmDialogProvider = ({ children }) => {
  const [context, setContext] = useState({
    isOpen: false,
    title: "",
    message: "",
    onClose: () => {},
  });

  return (
    <ConfirmDialogContext.Provider value={{ ...context, setContext }}>
      {children}
    </ConfirmDialogContext.Provider>
  );
};

3.使用上下文挂钩
ConfirmDialog组件应该使用useContext钩子来获取上下文。

export const ConfirmDialog = () => {
  const { isOpen, title, message, onClose } = useContext(ConfirmDialogContext);

  return isOpen && (
    <ModalDialog header={title} onClose={onClose} closeButtonText='Confirm'>
      <Text>{message}</Text>
    </ModalDialog>
  );
};

显示确认模式

export const ShowConfirmModal = (title, message, onClose) => {
  const { setContext } = useContext(ConfirmDialogContext);

  setContext({
    isOpen: true,
    title,
    message,
    onClose,
  });
};

最后在APP函数中使用ConfrimDialogProvider

相关问题