NextJS 16, use child component in a parent component #204025
Replies: 4 comments 2 replies
|
You're right — just importing it won't let the parent control the modal. The modal state lives inside the child. The parent can't reach in and flip it open unless you expose a way to do that. 1. Lift state up (simplest) // Parent
const [showModal, setShowModal] = useState(false);
return (
<>
<button onClick={() => setShowModal(true)}>Open from parent</button>
<CounterModal isOpen={showModal} onClose={() => setShowModal(false)} />
</>
);
// Child (CounterModal)
export default function CounterModal({ isOpen, onClose }) {
// use isOpen / onClose instead of internal state
}
2. Forward a ref with useImperativeHandle (if you must keep state in child)
const Child = forwardRef((props, ref) => {
const [isOpen, setIsOpen] = useState(false);
useImperativeHandle(ref, () => ({
open: () => setIsOpen(true),
close: () => setIsOpen(false),
}));
// ...
});
// Parent
const childRef = useRef(null);
<button onClick={() => childRef.current?.open()}>Open</button>
<Child ref={childRef} />
Use sparingly — it breaks the "data flows down" mental model.
3. Controlled + uncontrolled hybrid (flexible)
Let the child manage its own state unless the parent passes isOpen — then it becomes controlled.
// Child
export default function CounterModal({ isOpen, onClose, defaultOpen = false }) {
const [internalOpen, setInternalOpen] = useState(defaultOpen);
const open = isOpen ?? internalOpen;
const setOpen = isOpen ? onClose : setInternalOpen; // simplified
// ...
}
Which to pick:
- Parent owns the trigger → lift state (#1)
- Child is a reusable library component → hybrid (#3)
- Weird legacy constraint → ref (#2)
Don't overthink it. Most of the time, lifting state is the cleanest. The child becomes dumber (just UI), the parent
decides when it shows. |
|
It depends on how your modal is implemented. If the modal state ( From my experience, the cleanest approach is to lift the modal state up to the parent. Keep If you can share a small code snippet of your parent and child components, it'll be much easier to suggest the best approach. |
This comment was marked as low quality.
This comment was marked as low quality.
|
Importing the child component is enough if the parent only needs to display it and the modal is still opened from the button inside the child. However, if a button in the parent should open the modal inside the child, the parent needs some way to control it. Since you are using the Tailwind command API, the parent button can target the dialog rendered by the child. The important part is that function ParentComponent() {
return (
<>
<button
type="button"
command="show-modal"
commandFor="counter-dialog"
>
Open modal
</button>
<ChildComponent />
</>
);
}function ChildComponent() {
return (
<el-dialog>
<dialog id="counter-dialog">
<p>Modal content</p>
<button
type="button"
command="close"
commandFor="counter-dialog"
>
Close
</button>
</dialog>
</el-dialog>
);
}So you do not need to copy the child component code into the parent. Keep the modal in the child and let the parent button reference its dialog ID. |
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
🏷️ Discussion Type
Question
Body
I have a child component (a simple counter) with a button and a modal. When clicking the button the modal opens. This works only in the child component. Now I need to add this functionality in a parent component. Just importing this component into the parent will not be enough I think?
Guidelines
All reactions