S
SolidJS13mo ago
Grahf

solidJS equivalent of react's cloneElement

I'm trying to convert a react component that uses cloneElement to a solidJS component. I've briefly glanced at some of the messages on discord concerning cloneElement and I haven't seen anything definitive. lxsmnsyc mentioned using solid-headless. Original react code:
import React from 'react';
import T from 'prop-types';

import allowed from '../utils/allowed';

function Thead(props) {
const { children } = props;

return (
<thead data-testid="thead" {...allowed(props)}>
{React.cloneElement(children, { inHeader: true })}
</thead>
);
}

Thead.propTypes = {
children: T.node,
};

Thead.defaultProps = {
children: undefined,
};

export default Thead;
import React from 'react';
import T from 'prop-types';

import allowed from '../utils/allowed';

function Thead(props) {
const { children } = props;

return (
<thead data-testid="thead" {...allowed(props)}>
{React.cloneElement(children, { inHeader: true })}
</thead>
);
}

Thead.propTypes = {
children: T.node,
};

Thead.defaultProps = {
children: undefined,
};

export default Thead;
This is as far as I got with my solidJS conversion:
import allowed from '../utils/allowed'

export const Thead = (props: any) => {

return (
<thead data-testid='thead' {...allowed(props)}>
{React.cloneElement(props.children, { inHeader: true })}
</thead>
)
}
import allowed from '../utils/allowed'

export const Thead = (props: any) => {

return (
<thead data-testid='thead' {...allowed(props)}>
{React.cloneElement(props.children, { inHeader: true })}
</thead>
)
}
This is what chatGPT recommended:

<thead data-testid="thead" {...allowed(props)}>
{props.children && typeof props.children === 'function' ? children({ inHeader: inHeader() }) : null}
</thead>

<thead data-testid="thead" {...allowed(props)}>
{props.children && typeof props.children === 'function' ? children({ inHeader: inHeader() }) : null}
</thead>
6 Replies
lxsmnsyc
lxsmnsyc13mo ago
I never mentioned it. Any link? you should also consider @thetarnav 's previous message https://discord.com/channels/722131463138705510/722131463889223772/1174823721077325874
Grahf
GrahfOP13mo ago
Grahf
GrahfOP13mo ago
Oh he warned me. Think this is beyond me
lxsmnsyc
lxsmnsyc13mo ago
yeah you basically have to rethink how to approach this
thetarnav
thetarnav13mo ago
lmao I knew this will be an issue as soon I as saw cloneElement what chat gpt recommended is kinda in the right way, but it doesn't show why from what I understand, in react, this source jsx:
<Table>
<Thead>
<Tr>
<Th>Event</Th>
<Th>Date</Th>
<Th>Location</Th>
</Tr>
</Thead>
<Tbody>
<Tr>
<Td>Tablescon</Td>
<Td>9 April 2019</Td>
<Td>East Annex</Td>
</Tr>
<Tr>
<Td>Capstone Data</Td>
<Td>19 May 2019</Td>
<Td>205 Gorgas</Td>
</Tr>
</Tbody>
</Table>
<Table>
<Thead>
<Tr>
<Th>Event</Th>
<Th>Date</Th>
<Th>Location</Th>
</Tr>
</Thead>
<Tbody>
<Tr>
<Td>Tablescon</Td>
<Td>9 April 2019</Td>
<Td>East Annex</Td>
</Tr>
<Tr>
<Td>Capstone Data</Td>
<Td>19 May 2019</Td>
<Td>205 Gorgas</Td>
</Tr>
</Tbody>
</Table>
should give you this html on desktop:
<table>
<thead>
<tr>
<th>Event</th>
<th>Date</th>
<th>Location</th>
</tr>
</thead>
<tbody>
<tr>
<td>Tablescon</td>
<td>9 April 2019</td>
<td>East Annex</td>
</tr>
<tr>
<td>Capstone Data</td>
<td>19 May 2019</td>
<td>205 Gorgas</td>
</tr>
</tbody>
</table>
<table>
<thead>
<tr>
<th>Event</th>
<th>Date</th>
<th>Location</th>
</tr>
</thead>
<tbody>
<tr>
<td>Tablescon</td>
<td>9 April 2019</td>
<td>East Annex</td>
</tr>
<tr>
<td>Capstone Data</td>
<td>19 May 2019</td>
<td>205 Gorgas</td>
</tr>
</tbody>
</table>
and on mobile:
<table>
<tbody>
<tr>
<td><div>Event</div>Tablescon</td>
<td><div>Date</div>9 April 2019</td>
<td><div>Location</div>East Annex</td>
</tr>
<tr>
<td><div>Event</div>Capstone Data</td>
<td><div>Date</div>19 May 2019</td>
<td><div>Location</div>205 Gorgas</td>
</tr>
</tbody>
</table>
<table>
<tbody>
<tr>
<td><div>Event</div>Tablescon</td>
<td><div>Date</div>9 April 2019</td>
<td><div>Location</div>East Annex</td>
</tr>
<tr>
<td><div>Event</div>Capstone Data</td>
<td><div>Date</div>19 May 2019</td>
<td><div>Location</div>205 Gorgas</td>
</tr>
</tbody>
</table>
more or less at least in react you can modify the jsx data structure after it was called and before it was rendered but in solid jsx resolves to html element directly so it's too late you need to be able to get the right result the moment you call all the jsx elements this is why you usually use callbacks to make the evaluation lazy, so you have additional time to decide where and how many times to call it. Like <For> and <Show> components do. maybe it would be the easiest to do it by providing the data up-front and focus only on th an td elements
const { Th, Td } = createResponsiveTable(
["Event", "Date", () => <span>Location</span>]
)

<table>
<thead>
<tr>
<Th i={0}/>
<Th i={1}/>
<Th i={2}/>
</tr>
</thead>
<tbody>
<tr>
<Td i={0}>Tablescon</Td>
<Td i={1}>9 April 2019</Td>
<Td i={2}>East Annex</Td>
</tr>
<tr>
<Td i={0}>Capstone Data</Td>
<Td i={1}>19 May 2019</Td>
<Td i={2}>205 Gorgas</Td>
</tr>
</tbody>
</table>
const { Th, Td } = createResponsiveTable(
["Event", "Date", () => <span>Location</span>]
)

<table>
<thead>
<tr>
<Th i={0}/>
<Th i={1}/>
<Th i={2}/>
</tr>
</thead>
<tbody>
<tr>
<Td i={0}>Tablescon</Td>
<Td i={1}>9 April 2019</Td>
<Td i={2}>East Annex</Td>
</tr>
<tr>
<Td i={0}>Capstone Data</Td>
<Td i={1}>19 May 2019</Td>
<Td i={2}>205 Gorgas</Td>
</tr>
</tbody>
</table>
Want results from more Discord servers?
Add your server