0

What I need to achieve is to handle a specific attribute from one JSX component that I import to its parent component in a way that I will display here.

Child component returns JSX with 'someId' attribute:

return <h1 someId={123}>{title}</h1>

And the parent assigns this JSX to a variable and then needs to read this 'someId' attribute from it - before mounting the variable to the DOM:

let mySpecialChild = <Child title="Hello boys and girls!" />
let mySpecialChildId = mySpecialChild.someId

mySpecialChild.someId is now empty. I know it looks strange and against ReactJS rules but I need this for a very specific use case (in a loop, with additional conditions related to this child attribute). Here I created a sandbox for tests:

https://codesandbox.io/s/small-wood-jx33sz?file=/src/App.js

General Grievance
  • 4,555
  • 31
  • 31
  • 45
Vlado
  • 3,517
  • 2
  • 26
  • 24
  • You cannot, because the `Child` function has not been executed yet, so the returned DOM has not been created yet. You could use `ref`s if it fits your needs. – Gabriele Petrioli Aug 07 '22 at 12:28

3 Answers3

1

You should set a state on the parent component. codesandbox

  1. Define a state which holds the id in the parent component.
  2. Pass the function that sets the state (setSomeId) to the child component from the parent component.
  3. Call setState function(setSomeId) when you want.
  4. The state of parent component will update, so it will rerender with the new value of someId.

Edit:

Notice that the state setter function you pass will not change during renders. React docs state that:

React guarantees that setState function identity is stable and won’t change on re-renders.

There other ways for doing what you want:

  1. useImperativeHandle: If you want to read the child id imperatively, you can pass a ref to the child component from the parent component and use useImperativeHandle hook inside the child component. You can call ref.current?.getId function from the parent component. Notice that if you want to display the id in the parent component, the parent component should be rerendered. So you will see the child id when you press the button that updates the state, and rerenders the parent component. codesandbox

  2. Ref callback: If you don't need to render the value of someId from the child component and you want to call a function whenever the child id changes, you can pass a ref callback from the parent component to the child component. The callback gets called whenever the node is changed. You can access the property you want from the callback. If you want to render someId on the screen, you have to render the parent component. So you should set its value to state. (I changed someId to data-some-id because someId is not a valid prop on a DOM element. codesandbox.

c0m1t
  • 1,089
  • 1
  • 7
  • 16
1

You can work around this issue by not using JSX to render that component, but directly calling it.

Disclaimer: You should not be using this approach.

If you want the returned DOM representation directly, you will have to call the Child component as a function instead of a JSX.

So if instead of
let mySpecialChild = <Child title="Hello boys and girls!" />
you do
let mySpecialChild = Child({title:"Hello boys and girls!"}),

then you can do let mySpecialChildId = mySpecialChild.props.someId;

Updated demo at: https://codesandbox.io/s/nameless-feather-fwdhs4

Gabriele Petrioli
  • 191,379
  • 34
  • 261
  • 317
  • Works but not in my loop. It is not stable, as you said. Thank you - it is something good to be known. I will redesign my app a little, with different approach. – Vlado Aug 07 '22 at 17:30
0

You can access props as:

CODESANDBOX LINK

let mySpecialChild = <Child title="Hello boys and girls!" />;
console.log(mySpecialChild.props.title);

when you console.log mySpecialChild then It will log as:

enter image description here

DecPK
  • 24,537
  • 6
  • 26
  • 42
  • The OP want the attribute added to the returned value, the `id` given from the `Child` component. – Gabriele Petrioli Aug 07 '22 at 12:11
  • @GabrielePetrioli I've been through question again and not able to find out where OP wants the attribute added to the returned value. *mySpecialChild.someId is now empty* AFAIT OP want to know the props before the `mySpecialChild` gets mounted our used in `JSX`. Do let me know if I'm understood wrong – DecPK Aug 07 '22 at 12:15
  • They want the `someid` attribute that is part of the rendering of `Child`, but want to access it from the parent component. – Gabriele Petrioli Aug 07 '22 at 12:18