hyperx
hyperx copied to clipboard
How to pass function as child?
:wave: hi, wondering how to pass a function to a component. Trying to use the Query
component from react-apollo
.
const hyperx = require('hyperx');
const { Query } = require('react-apollo');
const gql = require('graphql-tag');
const { createElement } = require('react');
const hx = hyperx(createElement);
hx`<${Query}
query=${gql`
{
// query here
}
`}
>
${({ loading, error, data }) => {
// function content here
}}
</${Query}>`
Returns:
Failed prop type: Invalid prop `children` of type `array` supplied to `Query`, expected `function`.
in Query
@goto-bus-stop @substack is passing a function as a child possible at all?
I don't think so. it might work if you pass it as the children=${fn}
prop instead though
@goto-bus-stop ah okay, thank you for you reply!
That's a bummer, I've been looking around for a JSX alternative because I don't like the magic, seems that there is no replacement out there yet.
This isn't restricted to apollo btw. I've seen react components accept functions before. Just tested with GatsbyJS too:
import React from 'react';
import { StaticQuery, graphql } from 'gatsby';
import hyperx from 'hyperx';
const hx = hyperx(React.createElement);
export default ({ children }) => hx`
<${StaticQuery}
query=${graphql`
{
site {
siteMetadata {
title
}
}
}
`}
render=${() => {}}
/>
`;
Interestingly enough this gives a different error though: Objects are not valid as a React child (found: object with keys {query, render}). If you meant to render a collection of children, use an array instead.
. Probably because this is a self closing tag.
Funny thing is the above is a pretty bad example, I would say the following using just createElement
is even more readable:
import { createElement } from 'react';
import { StaticQuery, graphql } from 'gatsby';
export default ({ children }) => createElement(
StaticQuery,
{
query: graphql`
{
site {
siteMetadata {
title
}
}
}
`,
render: () => {},
}
);
Though mixing hyperx
and the use of createElement
could be very confusing to some developers. I'll keep poking. :)
We could probably loosen the type check to allow function children, but I also agree that using createelement is nicer. I'd alias it to something like h
and use it for all custom components, then just use hyperx for the native HTML nodes. you could also look into hyperscript (there is a react version of it but I forgot the name) if you haven't already, it's like a fancier createElement function, no template strings
Hmm loosening the type check could be desirable because I'm not sure if in all cases createElement
is nicer... Thanks for the tip, I know hyperscript but prefer hyperx because it's closer to HTML.