React Context API不适用于单个应用程序对话框

AMS777

我想创建一个对话框组件以呈现一次并在整个应用程序中使用它,而不是每次需要显示对话框时都创建一个对话框组件。

上下文API最初正确显示了对话框。如果对话框仅包含静态文本,则可以正确显示。但是,如果对话框包含任何动态元素,则它不会对更改做出反应。

我使用自定义钩子处理对话框。

这是一个带有静态文本的对话框示例,该对话框有效

export function useStaticTextDialog(callback) {
  const appContext = useContext(AppContext);

  const openDialog = () => appContext.openAppDialog(appDialogContext);
  const onDialogOk = () => {
    appContext.closeAppDialog(); // close unique app dialog first in case the callback uses it
    callback();
  };

  const appDialogContext = {
    title: 'Static text',
    content: 'This static text works.',
    onOk: onDialogOk,
    onClose: appContext.closeAppDialog,
  };

  return { open: openDialog };
}

它的名称如下:

 const staticTextDialog = useStaticTextDialog(callback);
 staticTextDialog.open();

单个组件在App组件中呈现一次

import AppDialog from 'components/appDialog';

function App() {
  return (
    <AppContextProvider>
      <Router />
      <AppDialog />
    </AppContextProvider>
  );
}

上下文非常简单:

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

const AppContext = createContext();

function AppContextProvider({ children }) {
  const [isAppDialogOpen, setIsAppDialogOpen] = useState(false);
  const [appDialogContext, setAppDialogContext] = useState({});

  const openAppDialog = appDialogContext => {
    setAppDialogContext(appDialogContext);
    setIsAppDialogOpen(true);
  };
  const closeAppDialog = () => setIsAppDialogOpen(false);

  const appContextValue = {
    isAppDialogOpen,
    appDialogContext,
    openAppDialog,
    closeAppDialog,
  };

  return <AppContext.Provider value={appContextValue}>{children}</AppContext.Provider>;
}

export { AppContext, AppContextProvider };

好吧,到目前为止可行。但是,如果将动态元素添加到对话框中,则它不会对更改做出反应并显示陈旧的值:

export function useDynamicTextDialog(callback) {
  const appContext = useContext(AppContext);
  const [name, setName] = useState();

  const openDialog = newName => {
    setName(newName);
    appContext.openAppDialog(appDialogContext);
  };
  const onDialogOk = () => {
    appContext.closeAppDialog(); // close unique app dialog first in case the callback uses it
    callback(name);
  };

  const appDialogContext = {
    title: 'Overwrite warning',
    content: `The name "${name}" already exists. Are you sure you want to overwrite it?`,
    onOk: onDialogOk,
    onClose: appContext.closeAppDialog,
  };

  return { open: openDialog };
}

如果对话框包含表单元素(例如文本框或下拉列表),则该对话框也将不起作用。它不会对用户的新值做出反应。

我发现此行为是意外的,我认为它应该对更改做出反应并正常工作。实际上,当呈现多个对话框组件时(每次需要一个对话框时),这种方法同样有效在这种情况下,不使用上下文API。例:

import DialogTemplate from 'components/dialogTemplate';

export function useDynamicTextDialog(callback) {
  const [isDialogOpen, setIsDialogOpen] = useState(false);
  const [name, setName] = useState();

  const openDialog = newName => {
    setName(newName);
    setIsDialogOpen(true);
  };
  const closeDialog = () => setIsDialogOpen(false);
  const onDialogOk = () => {
    closeDialog ();
    callback(name);
  };

  const dialogContext = {
    title: 'Overwrite warning',
    content: `The name "${name}" already exists. Are you sure you want to overwrite it?`,
    onOk: onDialogOk,
    onClose: closeDialog,
  };

  const Dialog = <DialogTemplate dialogContext={dialogContext} />;

  return { Dialog, open: openDialog };
}

然后它在某个地方打开,就像单个应用程序对话框一样:

 const dynamicTextDialog = useDynamicTextDialog(callback);
 dynamicTextDialog.open();

但是在这种情况下,必须渲染每个对话框组件

function Component() {
  const { dynamicTextDialog } = useDynamicTextDialog();

  return (
    <div>
      {...more elements}
      {applicationClosingWarningDialog.Dialog}
    </div>
  );
}

因此,如果使用20个对话框则必须渲染20个对话框组件,尽管它们的内容几乎相同。

这就是为什么我只想对整个应用程序使用一个对话框组件,每次都重复使用它,并只是更改内容。但是上下文API不起作用。

为什么即使使用相同的方式来处理对话框模板的示例,也不能使用带有Context的应用程序对话框的示例,该示例为何起作用

如何使其与Context API一起使用?

AMS777

上下文API不会对对话框的更改做出反应,即使它的使用方式与有效的模板组件相同。

因此,对话框更改时必须专门触发渲染:

  useEffect(() => {
    appContext.setAppDialogContext(dialogContext);
  }, [name]);

完整的钩子:

export function useDynamicTextDialog(callback) {
  const appContext = useContext(AppContext);
  const [name, setName] = useState();
  
  useEffect(() => {
    appContext.setAppDialogContext(dialogContext);
  }, [name]);

  const openDialog = newName => {
    setName(newName);
    appContext.openAppDialog(appDialogContext);
  };
  const onDialogOk = () => {
    appContext.closeAppDialog(); // close unique app dialog first in case the callback uses it
    callback(name);
  };

  const appDialogContext = {
    title: 'Overwrite warning',
    content: `The name "${name}" already exists. Are you sure you want to overwrite it?`,
    onOk: onDialogOk,
    onClose: appContext.closeAppDialog,
  };

  return { open: openDialog };
}

带有模板的对话框和单个对话框应用程序的演示:

https://ams777.github.io/react-single-app-dialog

演示代码:

https://github.com/AMS777/react-single-app-dialog

本文收集自互联网,转载请注明来源。

如有侵权,请联系[email protected] 删除。

编辑于
0

我来说两句

0条评论
登录后参与评论

相关文章

来自分类Dev

React Context API +钩子

来自分类Dev

React 应用程序运行良好,但不适用于移动浏览器

来自分类Dev

对话框抛出“无法添加窗口-令牌null不适用于应用程序”

来自分类Dev

React Context API与本地存储

来自分类Dev

使用Typescript的React的Context API

来自分类Dev

Formik的setFieldValue不适用于来自Context API的值

来自分类Dev

创建对话框“令牌空值不适用于应用程序”对话框时,Logcat引发错误

来自分类Dev

从React的Context API组件重定向

来自分类Dev

从服务显示警报对话框时获取异常-无法添加窗口-令牌null不适用于应用程序

来自分类Dev

警报对话框异常“无法添加窗口 - 令牌 null 不适用于应用程序”,我应该提供什么上下文?

来自分类Dev

getUserMedia API在React中不适用于iOS Safari

来自分类Dev

在现有iOS应用程序中使用React Native仅适用于某些视图

来自分类Dev

适用于移动应用程序的Ionic React-水平滚动与屏幕外的元素

来自分类Dev

React / Context API / TypeScript:如何初始化Web应用程序并避免在状态更新时出现UI闪烁?

来自分类Dev

Office 365 Outlook REST API - Office.context.mailbox.displayMessageForm 不适用于 Mac Outlook

来自分类Dev

我可以在Context API中使用React Context API还是必须将它们合并?

来自分类Dev

MDL组件不适用于React

来自分类Dev

适用于iOS的Google Plus API:共享功能-触摸本机对话框共享中的“公共”时崩溃的应用程序?

来自分类Dev

鞭尾或对话框不适用于ssh

来自分类Dev

换行内容不适用于对话框

来自分类Dev

如何在Redux中使用React Context API?

来自分类Dev

在React中使用Context API和功能组件作为服务

来自分类Dev

无法使用Context API React Native检索数据

来自分类Dev

具有多个值性能的React Context API

来自分类Dev

创建新对象时,使用React Context API更新组件

来自分类Dev

如何获取数据并存储在React Context API中?

来自分类Dev

无法从 React.Context API 获取提供者数据

来自分类Dev

React HOC 在 Lifecycle 方法中使用 Context API

来自分类Dev

使用 React Context API 时,无法获取数据

Related 相关文章

  1. 1

    React Context API +钩子

  2. 2

    React 应用程序运行良好,但不适用于移动浏览器

  3. 3

    对话框抛出“无法添加窗口-令牌null不适用于应用程序”

  4. 4

    React Context API与本地存储

  5. 5

    使用Typescript的React的Context API

  6. 6

    Formik的setFieldValue不适用于来自Context API的值

  7. 7

    创建对话框“令牌空值不适用于应用程序”对话框时,Logcat引发错误

  8. 8

    从React的Context API组件重定向

  9. 9

    从服务显示警报对话框时获取异常-无法添加窗口-令牌null不适用于应用程序

  10. 10

    警报对话框异常“无法添加窗口 - 令牌 null 不适用于应用程序”,我应该提供什么上下文?

  11. 11

    getUserMedia API在React中不适用于iOS Safari

  12. 12

    在现有iOS应用程序中使用React Native仅适用于某些视图

  13. 13

    适用于移动应用程序的Ionic React-水平滚动与屏幕外的元素

  14. 14

    React / Context API / TypeScript:如何初始化Web应用程序并避免在状态更新时出现UI闪烁?

  15. 15

    Office 365 Outlook REST API - Office.context.mailbox.displayMessageForm 不适用于 Mac Outlook

  16. 16

    我可以在Context API中使用React Context API还是必须将它们合并?

  17. 17

    MDL组件不适用于React

  18. 18

    适用于iOS的Google Plus API:共享功能-触摸本机对话框共享中的“公共”时崩溃的应用程序?

  19. 19

    鞭尾或对话框不适用于ssh

  20. 20

    换行内容不适用于对话框

  21. 21

    如何在Redux中使用React Context API?

  22. 22

    在React中使用Context API和功能组件作为服务

  23. 23

    无法使用Context API React Native检索数据

  24. 24

    具有多个值性能的React Context API

  25. 25

    创建新对象时,使用React Context API更新组件

  26. 26

    如何获取数据并存储在React Context API中?

  27. 27

    无法从 React.Context API 获取提供者数据

  28. 28

    React HOC 在 Lifecycle 方法中使用 Context API

  29. 29

    使用 React Context API 时,无法获取数据

热门标签

归档