简体   繁体   中英

How to show the dialog everywhere in the app on clicking a button using react and typescript?

i want to display a dialog on clicking additem and addbooks button using react and typescript.

what i am trying to do? I want to display a dialog on clicking additem button or addbooks button. this dialog will have hide button. on clicking this hide button the dialog should never appear again for the session.

Below is the code,

function MainComponent () {
    const [showDialog, setShowDialog] = React.useState(false);
    const openDialog = () => {
        setShowDialog(true);
    };
    const hideDialog = () => {
        setShowDialog(false);
    };
    return (
        <Route
            path="/items"
            render={routeProps => (
            <Layout>
                <Home
                    showDialog={showDialog} 
                    openDialog={openDialog}
                    hideDialog={hideDialog}
                    {...routeProps}
               />
              {showDialog && (
                  <Dialog
                      hideDialog={hideDialog}
                  />
              )}
              </Layout>
          )}
      />

      <Route
        path="/items/:Id/books/:bookId"
        render={routeProps => (
          <Layout>
              <Books
                openDialog={openDialog}
                {...routeProps}
              />
              {showDialog && (
                <Dialog
                  hideDialog={hideDialog}
                />
              )}
          </Layout>
      )}
  </>

)

function Home ({openDialog}: Props) {
    return (
        <button Onclick={openDialog}>AddItem</Button>
    )
}

function Books ({openDialog}: Props){
    return (
        <button onClick={openDialog}>AddBooks</Button>
    )
}

function MessageDialog({hideDialog}: Props) {
    return (
        <button onClick={hideDialog}>hide</button>
    )
}

Now the question is as you see i am rendering MessageDialog in two places based on showDialog value. if users clicks additems button the dialog is displayed and when user to navigates to other view and clicks addbooks button the dialog is displayed.

somehow i feel this is not the right approach or something is missing...

How can i create a global dialog component that is accessible anywhere from my app or using toastify or some better approach. could someone help me with this. thanks.

I think your code is pretty good, but I can think of two minor things that could potentially improve it.

Firstly, you have some duplicate code in your main component. You should be able to move the Dialog outside of the routes. Like so:

return (<>
    {showDialog && (
        <Dialog
            hideDialog={hideDialog}
        />
    )}
    <Route ... />
    <Route ... />
</>)

This will render your dialog no matter which route is matched.

Secondly, instead of passing openDialog and hideDialog callbacks as props, you could create a React context. This is optional, and dependning on the case this might not be desired. A React context is slightly more complex than just a callback, so it adds complexity to your code. The benefit is that the callbacks doesn't need to be passed down through the props of every child component, which makes the component structure cleaner if you have a large component tree.

To create a React context for this use case, you could do the following:

// Create a context with a default value of false
let DialogContext = React.createContext()

function MainComponent () {
    ...
    return (<DialogContext.Provider value={{ setDialogOpen: (open) => setShowDialog(open) }}>
        {showDialog && (
            <Dialog />
        )}
        <Route ... />
        <Route ... />
    </ DialogContext.Provider>)

}

function Home ({openDialog}: Props) {
    let dialogContext= useContext(DialogContext)
    return (
        <button onclick={() => dialogContext.setDialogOpen(true)}>AddItem</Button>
    )
}

function Books ({openDialog}: Props){
    let contextValue = useContext(DialogContext)
    return (
        <button onClick={() => dialogContext.setDialogOpen(true)}>AddBooks</Button>
    )
}

function MessageDialog({hideDialog}: Props) {
    let dialogContext= useContext(DialogContext)
    return (
        <button onClick={() => dialogContext.setDialogOpen(false)}>hide</button>
    )
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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