qwik icon indicating copy to clipboard operation
qwik copied to clipboard

Using Slots/Children with Qwik-react

Open GuillemPM opened this issue 2 years ago • 4 comments

Qwik Version

0.10.0

Operating System (or Browser)

Windows 10

Node Version (if applicable)

16.14.0

Which component is affected?

Qwik React

Expected Behaviour

When creating a qwikify$ component, I should be able to access the children nodes or string. Example that should work (or similar) using ReactNode:

/** @jsxImportSource react */
import { qwikify$ } from "@builder.io/qwik-react";
import Alert, { AlertProps } from "@mui/material/Alert";

export const MUIAlert = qwikify$((props: { children?: React.ReactNode }) => {
    return (
        <>
           <Alert>{props.children}</Alert>
        </>
    )
})

Example that should work (or similar) using Slots:

/** @jsxImportSource react */
import { Slot } from "@builder.io/qwik";
import { qwikify$ } from "@builder.io/qwik-react";
import Alert, { AlertProps } from "@mui/material/Alert";

export const MUIAlert = qwikify$((props: AlertProps) => {
    return (
        <>
           <Alert {...props}>
              <Slot/>
           </Alert>
        </>
    )
})

Actual Behaviour

Using the code below gives the following errors:

Example using ReactNode:

Children is totally ignored (returns undefined) image

Adding any tag returns the following error: image

Type 'Element' is not assignable to type '((string | number | boolean | ReactElement<any, string | JSXElementConstructor<any>> | ReactFragment | ReactPortal) & (string | ... 6 more ... | JSXNode<...>)) | null | undefined'.
  Type 'JSXNode<string | FunctionComponent<Record<string, any>>>' is not assignable to type 'ReactPortal & JSXNode<string | FunctionComponent<Record<string, any>>>'.
    Property 'children' is missing in type 'JSXNode<string | FunctionComponent<Record<string, any>>>' but required in type 'ReactPortal'

Example using Slots:

This won't work since you can't use Qwik components inside Qwik-react components, but maybe it should.

C:\Users\path\to\repository\node_modules\react-dom\cjs\react-dom-server-legacy.node.development.js:6183
    throw new Error("Objects are not valid as a React child (found: " + (childString === '[object Object]' ? 'object with keys {' + Object.keys(node).join(', ') + '}' : childString) + "). " + 'If you meant to render a collection of children, use an array ' + 'instead.');
          ^

Error: Objects are not valid as a React child (found: object with keys {type, props, key}). If you meant to render a collection of children, use an array instead.

Additional Information

Maybe I'm missing something, or it is not intended to work at the moment, whoever I couldn't find any clear information about this in the docs/discord

GuillemPM avatar Oct 11 '22 10:10 GuillemPM

I had @GuillemPM open this as a bug report because I wasn't sure if it was possible or could be possible.

If it's expected behavior but possible in the future maybe this can be converted to a feature request instead if closing.

nnelgxorz avatar Oct 11 '22 11:10 nnelgxorz

This is likely a feature, since it;s not trivial to make this work

manucorporat avatar Oct 19 '22 14:10 manucorporat

This is likely a feature, since it;s not trivial to make this work

Could I kindly ask how are we supposed to send children to React components then?

Imagine I want to send the Items from the parent? image

My code:

<MyQwikifiedStack>
  <Item>Data from the storage</Item>
  <Item>Data from the storage</Item>
</MyQwikifiedStack>

I cannot use the Slot, or children in "MyQwikifiedStack.tsx", it returns undefined or error.

GuillemPM avatar Oct 19 '22 16:10 GuillemPM

This is likely a feature, since it;s not trivial to make this work

For it to actually make sense children inside qiwk-react components should totally work.

I have actually encountered a situation where this could've helped a lot. When trying to work with react-hook-form and qwik-react I found out I could not prevent the default event for form submition from inside the qwik-react component. So the solution I first thought of was wrap a qwik form with preventdefault:submit in my qwik-react react-hook-form wrapper and call more react components as children of the qwik form with the submit default prevented.

CristianCiubancan avatar Oct 19 '22 20:10 CristianCiubancan

This was implemented in latest release!!

manucorporat avatar Nov 01 '22 20:11 manucorporat