Can you re-use React elements across different renders and contexts?

Viewed 64

I've got a component like this:

const Foo = () => (
  <div>
    <h1>Hello world!</h1>
  </div>
)

Note that it doesn't take any props; it returns the same JSX on every render

Could this be used as just a constant instead of a function?

const Foo = (
  <div>
    <h1>Hello world!</h1>
  </div>
)

or will React have problems re-using the exact same React.createElement() result across re-renders and - more likely - in different DOM contexts throughout the app?

const OtherComponent = ({ ... }) => (
  <div>
    {Foo}
    {...}
  </div>
)

const OtherOtherComponent = ({ ... }) => (
  <span>
    {Foo}
  </span>
)

EDIT: It crossed my mind that any hooks getting called inside child components are probably going to get messed up by this, so it's probably a bad idea.

EDIT 2: Disregard the first "EDIT"; I tested it out and was surprised to find that a hook buried under the const react-node does actually get called multiple times. I'm leaning towards thinking this is indeed safe, but would still like confirmation from someone more familiar with React's internals.

Using hook within constant node

2 Answers

Sure you can use the just jsx assigned to a variable, if there are no complex stuff. Ref: for acknowledge

Updated with the POC: enter image description here

This is just javascript. In first case, you create an object whose reference is not changed if you keep using it again and again.

In the other case its a function and everytime it is invoked, a new instance/object is returned.

A demonstration of the same,

const Comp1 = <div>Comp 1</div>;

const Comp2 = () => {
  console.log('rendering comp 2' + Math.random());
  return  <div>Comp 2</div>;
};

export default function App() {
  const obj1 = Comp1;
  const obj2 = Comp1;
  const obj3 = Comp1;

  console.log(Object.is(obj1, Comp1));
  console.log(Object.is(obj1, obj2));

  console.log(Object.is(obj2, Comp1));
  console.log(Object.is(obj2, obj3));

  return (
    <div>
      {obj1}
      {obj2}
      {obj3}
      <Comp2/>
      <Comp2/>
      <Comp2/>
    </div>
  );
}

Related