javascript - How to check if a child element exists in parent in React? - Stack Overflow

admin2025-04-18  0

I have a ponent structure as follows:

const Parent = (props) => {
  return <div>{props.children}</div>;
};

const Child1 = (props) => {
  return <h2>child 1</h2>;
};

const Child2 = (props) => {
  return <h2>child 2</h2>;
};

And I create an instance as follows:

const node = <Parent>
  <Child1 />
  <Child2 />
</Parent>

Now, as I am exposing this to outside world, users might forget to pass <Child1 /> or <Child2 /> in the parent. I want to detect this in the parent and then render something else based on if <Child2 /> was passed or not.

What I tried: I have made use of the context API to have some munication between parent and child. I am looking for something simpler than this.

Something like this: .js#L69

I have a ponent structure as follows:

const Parent = (props) => {
  return <div>{props.children}</div>;
};

const Child1 = (props) => {
  return <h2>child 1</h2>;
};

const Child2 = (props) => {
  return <h2>child 2</h2>;
};

And I create an instance as follows:

const node = <Parent>
  <Child1 />
  <Child2 />
</Parent>

Now, as I am exposing this to outside world, users might forget to pass <Child1 /> or <Child2 /> in the parent. I want to detect this in the parent and then render something else based on if <Child2 /> was passed or not.

What I tried: I have made use of the context API to have some munication between parent and child. I am looking for something simpler than this.

Something like this: https://github./mui-org/material-ui/blob/next/packages/mui-lab/src/TimelineItem/TimelineItem.js#L69

Share Improve this question asked Sep 8, 2021 at 13:34 vighnesh153vighnesh153 5,4263 gold badges23 silver badges43 bronze badges 4
  • If you're expecting a set amount of very specific ponents, why not pass them as separate props instead of using children? It would be very tricky to check it like that, whilst having a prop of renderChildOne or something like that would make it way easier to check – Ron B. Commented Sep 8, 2021 at 13:47
  • That will definitely be easier. But having an XML like syntax feels a bit more natural to me. So, was trying to see if there is some easy way to do this without using context-api. – vighnesh153 Commented Sep 8, 2021 at 13:50
  • Well, JSX is not exactly XML or HTML like, it's more of a syntactic sugar for function calls. So if you expect a constant amount of ponents, it's better to pass them as props. You'll see that a lot in libraries like Material UI, for example their Autoplete ponent expects a prop called renderInput, instead of checking whether one of the children contains an input. So that's definitely the better pattern. – Ron B. Commented Sep 8, 2021 at 13:55
  • I am actually trying to something like Material UI. You can check this timeline ponent: material-ui./ponents/timeline/#opposite-content. Here, the TimelineOppositeContent is optional. And this is how they check if user has passed "TimelineOppositeContent" or not: github./mui-org/material-ui/blob/next/packages/mui-lab/src/… – vighnesh153 Commented Sep 8, 2021 at 14:00
Add a ment  | 

2 Answers 2

Reset to default 2

If only the number of children is important then:

  const count = React.Children.count(children);

To check specific ponents:

   let child1Exists = false;
let child2Exists = false;
    for (const key in props.children){
       const ponentName = props.children[key].type.name
        
       switch(ponentName){
         "Child1":
           child1Exists = true;
           break;
         "Child2":
           child2Exists = true;
           break;
         default: break;
        }  
    }
   
    if(child1exists && child2Exists){
      // All good!
    }

Its better to make this logic posable using higher order ponents.

This is the HOC. you can reuse it anywhere.

function withExpectedChildren(Component, expectedChildren = []) {
  return function Wrapped(props) {
    const hasAllExpectedChildren = expectedChildren.every((expectedChild) =>
      [props.children].flat().find((child) => child.type === expectedChild)
    );
    return hasAllExpectedChildren ? <Component {...props} /> : props.fallback;
  };
}

Wrap Parent ponent with the above HOC

const WrappedParent = withExpectedChildren(
  Parent,
  [Child1, Child2]
);

Render the posed ponent. It renders fallback, if any child misses.

<WrappedParent fallback={<h2>you missed a child</h2>}>
   <Child1 />
   <Child2 />
</WrappedParent>

You can see the working fiddle at https://jsfiddle/nqbL8g1m/

This is the idea, you shall modify it for your requirements

转载请注明原文地址:http://conceptsofalgorithm.com/Algorithm/1744970809a277474.html

最新回复(0)