#solidJS equivalent of react's cloneElement

10 messages · Page 1 of 1 (latest)

stoic agate
#

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;

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>
  )
}

This is what chatGPT recommended:

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

you should also consider @obsidian scroll 's previous message #general message

stoic agate
#

I've read a lot of the messages. Not sure which one

normal elbow
stoic agate
#

Oh

#

he warned me. Think this is beyond me

normal elbow
obsidian scroll
#

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>

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>

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>

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.