Samuel Hulla
Samuel Hulla

Reputation: 7099

Can you pass props to a JSX reference?

Before I begin with my question, allow me to clarify - the question here is a simplification of the issue, I'm working on an already large codebase on a legacy project for a client on short timespan and re-structuring the data would take me more time than trying to figure this out - I know this is not an ideal way to be try to be passing props around, so please don't just link to tutorial about how to be passing props

The gist of it is, I have a large array of objects, all of which have the following property { icon: <SomeJSXReference /> }
I basically created a re-usable abstraction component that returns the icon property based on certain passed props into it.

Issue is, i need to pass one of the props to the icon reference itself. Here's a rough pseudo-component I've written, to make it a bit clearer.

const objectsArray = [{ icon: <SpecificIcon /> }, /*...*/]
const Simplified = (props: { color: string }) => {
  const { color } = props
  const toRender = objectsArray.someOperationsLeadingToFinalObjectReference()
  return toRender.icon
}

What I need to do is somehow append a stroke={color} prop to the JSX referenced inside the toRender.icon pointer

Resulting basically in

Note: This does not explicitly have to be <SpecificIcon />, but rather whatever JSX.Element toRender.icon points to

Is there any way I could do this, that's not occuring to me?

Upvotes: 1

Views: 106

Answers (1)

Dennis Vash
Dennis Vash

Reputation: 53944

There are two ways you can do it.

  1. If the component already constructed (for what constructed means see JSX in Depth):
{ icon: <SpecificIcon /> }

You can use React.cloneElement:

[<Counter />].map(Component => React.cloneElement(Component, { num: 5 }))
  1. If the component not constructed (which is a better approach, because the function/constructor doesn't yet executed):
{ icon: SpecificIcon }

You can render it while passing props:

[Counter].map((Component, index) => <Component key={index} num={2} />)

See full example:

const Counter = ({ num = 0 }) => <div>{num}</div>;

const App = () => {
  return (
    <>
      <Counter />
      {[<Counter />].map(Component =>
        React.cloneElement(Component, { num: 4 })
      )}
      {[Counter].map((Component, index) => (
        <Counter key={index} num={2} />
      ))}
    </>
  );
};

Edit busy-zhukovsky-wxjhw

Upvotes: 2

Related Questions