Next.js Discord

Discord Forum

How to pass props to children?

Answered
Somali posted this in #help-forum
Open in Discord
Avatar
SomaliOP
Good afternoon. I have a question about building what seems like such a thing as a modal in Nex.
Essence:
The project has several modal windows, to implement them I use radix-ui prmitives

My idea is to create a Modal component and inside it pass any content through children, that is, overlay, the close button is the same for all modals.

The component itself looks like this:

The opening and closing logic is implemented by radix itself, but I can also control the opening state through useState.

I also have a Button component

Here the idea is that if there is a prop modalContent (And this is ReactElement), then I create a dialog trigger, which is shown in the Modal composition, inside which the dialog content is thrown through the children

It's used roughly like this.
<Button modalContent={<MainFormServer />}>
    Button
</Button>


I need all these wrappers, etc. only because the content in the modal can be a server component in which I need to receive data from the backend.

Perhaps I have complicated the structure too much, but I don’t know what other options there are.

Button - client comp
Modal - client comp
modalContent - server comp

Ideally, I would like the button component, based on some triggers, to be able to open a modal window with any content that I pass to it outside or inside.

The current solution certainly works, but it’s inconvenient, since I can’t call any closeAllMOdals method or close the current modal inside the component. To do this, I need to make the Modal component manageable, but since the Modal content is children, I can’t put open state props into it
I found a solution to how to pass props to children through React.CloneElement, but since I pass the componenet to <Button>, I have an error saying that Children object is not iterable or something like that.


Can you give me some tips for implementation?
Answered by Marchy
This sounds like a good use-case for the context api and a custom hook

You might also want to look at the parallel routes example, depending on what this will be used for

https://nextjs.org/docs/app/building-your-application/routing/parallel-routes#modals
View full answer

5 Replies

Avatar
SomaliOP
export const Button = ({
     className,
     intent
     size,
     children,
     modalContent,
     ...props
}) => {
     if (modalContent) {
         return (
             <Dialog.Root>
                 <Dialog.Trigger asChild>
                     <button
                         className={buttonStyles({ intent, size, className })}
                         {...props}
                     >
                         {children}
                     </button>
                 </Dialog.Trigger>
                 <Modal>{modalContent}</Modal>
             </Dialog.Root>
         );
     } else if (props.href) {
         return (
             <Link
                 {...props}
                 className={buttonStyles({ intent, size, className })}
             >
                 {children}
             </Link>
         );
     } else {
         return (
             <button
                 {...props}
                 className={buttonStyles({ intent, size, className })}
             >
                 {children}
             </button>
         );
     }
};


'use client';

import React, { useState } from 'react';

import * as Dialog from '@radix-ui/react-dialog';

import XClose from '/public/icons/x-close.svg';

export const Modal = ({ children }) => {
     return (
         <Dialog.Portal>
             <Dialog.Overlay className="DialogOverlay">
                 <Dialog.Close asChild>
                     <button
                         className=""
                         aria-label="Close"
                     >
                         <XClose />
                     </button>
                 </Dialog.Close>
             </Dialog.Overlay>
             <Dialog.Content className="DialogContent overflow-auto">
                 {children}
             </Dialog.Content>
         </Dialog.Portal>
     );
};
Avatar
This sounds like a good use-case for the context api and a custom hook

You might also want to look at the parallel routes example, depending on what this will be used for

https://nextjs.org/docs/app/building-your-application/routing/parallel-routes#modals
Answer
Avatar
SomaliOP
hmm, context api with <Dialog> comp inside?
Avatar
Sure. You could set the open/close state and the content as needed
Avatar
SomaliOP
yes, that is good solution, thank you