Matt
Matt

Reputation: 160

Is there a way to test if a React component is within another component of a particular type?

Let's for a second assume we have 3 components.

export class ComponentA extends React.Component<IComponentAProps, IComponentAState>{
    constructor(props: Readonly<IComponentAProps>) {
        super(props)
    }

    render() {
        return(
            <ComponentB />
        );
    }
}

export class ComponentB extends React.Component<IComponentBProps, IComponentBState>{
    constructor(props: Readonly<IComponentBProps>) {
        super(props)
    }

    render() {
        return(
            <ComponentC />
        );
    }
}

export class ComponentC extends React.Component<IComponentBProps, IComponentBState>{
    constructor(props: Readonly<IComponentBProps>) {
        super(props)
    }

    render() {
        return(
            <ComponentA />
        );
    }
}

Now obviously this is going to cause an infinite loop. Is there a way for me to check in ComponentC to see whether or not it is ultimately contained within an instance of ComponentA?

Upvotes: 1

Views: 133

Answers (1)

I'm not sure this is what you need, but you can achieve this using a React context.

import React, { createContext, FunctionComponent, useContext, useEffect } from 'react';

export const TopDogContext = createContext<string>('');

// The top dog can never be nested!
export const TopDog: FunctionComponent = ({ children }) => {
  const aboveMe = useContext(TopDogContext);

  useEffect(() => {
    if (aboveMe) {
      setTimeout(() => alert('Yo, you can\'t nest me!'));
      throw new Error('Yo, you can\'t nest me!');
    }
  }, [aboveMe]);

  return (
    <TopDogContext.Provider value={'I\'m the top dog!'}>
      { children }
    </TopDogContext.Provider>
  )
};


// -------
import { TopDog } from './top-dog';

function App() {
  <TopDog>
    <div className="App">
      [... YOUR APP HERE ...]
      {/* Will create an error if uncommented */}
      {/* <TopDog /> */}
    </div>
  </TopDog>
}

Note that you can still have multiple <TopDog>, but they will never have one being the ancestor of another.

Upvotes: 1

Related Questions