Home > Mobile >  React.cloneElement with deeply nested component
React.cloneElement with deeply nested component

Time:12-05

it's very complicated to explain the whole use-case here because I have deeply nested component, but I will try to show the concept.

How to display age from parent in OneMoreNestedChild without ContextApi, is it possible in the following example ?

Codesandbox

import React from "react";
import "./styles.css";

const OneMoreNestedChild = ({ age }) => {
  return (
    <>
      <p>One more nested child</p> Age: {age}
    </>
  );
};

const NestedChild = ({ children }) => {
  return (
    <>
      <p>Nested children</p> {children}
    </>
  );
};

const Child = ({ children }) => {
  return (
    <>
      <p>Child</p> {children}
    </>
  );
};

const Parent = ({ children }) => {
  const newChildren = React.Children.map(children, (child) =>
    React.cloneElement(child, { age: 1 })
  );

  return <div>{newChildren}</div>;
};

export default function App() {
  return (
    <div className="App">
      <Parent>
        <Child>
          <NestedChild>
            <OneMoreNestedChild />
          </NestedChild>
        </Child>
      </Parent>
    </div>
  );
}

CodePudding user response:

import React from "react";

const OneMoreNestedChild = React.forwardRef(({ age }, ref) => {
  return (
    <>
      <p>One more nested child</p>
      Age: {age}
    </>
  );
});

const NestedChild = ({ children }) => {
  return (
    <>
      <p>Nested children</p>
      {children}
    </>
  );
};

const Child = ({ children }) => {
  return (
    <>
      <p>Child</p>
      {children}
    </>
  );
};

const Parent = ({ children }) => {
  return (
    <NestedChild>
      {React.cloneElement(children, { age: 1 })}
    </NestedChild>
  );
};

In this example, the Parent component uses React.cloneElement() to update the age prop of the OneMoreNestedChild component and pass it down to the NestedChild component. However, since the OneMoreNestedChild component has been wrapped in a React.forwardRef() call, the Parent component can pass the age prop directly to the OneMoreNestedChild component, without creating a new component instance or causing intermediate components to re-render.

CodePudding user response:

In the code example, we can use React.cloneElement to clone the child element passed to the Parent component and pass it the age prop. We can then return the cloned element as part of the newChildren variable in the Parent component.

Here is an example of how this can be implemented:

import React from "react";
import "./styles.css";

const OneMoreNestedChild = ({ age }) => {
  return (
    <>
      <p>One more nested child</p> Age: {age}
    </>
  );
};

const NestedChild = ({ children }) => {
  return (
    <>
      <p>Nested children</p> {children}
    </>
  );
};

const Child = ({ children }) => {
  return (
    <>
      <p>Child</p> {children}
    </>
  );
};

const Parent = ({ children }) => {
  // Use React.cloneElement to clone the child element and pass it the age prop
  const newChildren = React.Children.map(children, (child) =>
    React.cloneElement(child, { age: 1 })
  );

  return <div>{newChildren}</div>;
};

export default function App() {
  return (
    <div className="App">
      <Parent>
        <Child>
          <NestedChild>
            <OneMoreNestedChild />
          </NestedChild>
        </Child>
      </Parent>
    </div>
  );
}

With this implementation, the age prop will be passed from the Parent component to the OneMoreNestedChild component and the age value will be displayed in the OneMoreNestedChild component.

One side thing though, it can become cumbersome to use if there are many deeply nested components and a large number of props that need to be passed down. In these cases, using the Context API may be a more efficient and scalable solution.

Hope it helps!

  • Related