1

Is there a way to access a React component by name? For example, using React devtools, I can search through components and access the most recently selected one in the console by using $r. Is there a way to access these components without React devtools? I.e. is there a query I can use to grab these components?

Some more information: I am interested in writing a chrome extension for a specific webpage that uses react. I know the name of the component I want to interact with, I'm just not sure how to actually access it.

4
  • Why it's your use case fo that ? Commented Sep 5, 2015 at 6:25
  • Sorry, I should have been more clear. I've added some extra information. Commented Sep 5, 2015 at 15:51
  • It's hard to know what precisely you mean by name of component in this case -- you haven't clarified and there is no example code. Commented Sep 5, 2015 at 15:54
  • Assuming you have control over the programmatic response of components to being selected, you should pass all components a common handler function which resides in a common ancestor component. Commented Sep 5, 2015 at 15:56

2 Answers 2

1

Here's a function to traverse and transform into a tree structure a react component hierarchy. Just access component's name with c.constructor.name:

const {
  isDOMComponent,
  getRenderedChildOfCompositeComponent,
  findRenderedComponentWithType
} = React.addons.TestUtils;

function traverse(c, node) {
  if (isDOMComponent(c)) {
    return;
  }

  node.children.push({
    name: c.constructor.name,
    children: []
  });

  const ccc = getRenderedChildOfCompositeComponent(c);

  if (isDOMComponent(ccc)) {
    React.Children.forEach(ccc.props.children, function traverseCompositeChildrenOf(child) {
      if (child.type) {
        const cccc = findRenderedComponentWithType(ccc, child.type);
        traverse(cccc, getNode(node, c.constructor.name));
      }
    });
  } else {
    traverse(ccc, getNode(node, c.constructor.name));
  }
}

Use it like this:

const root = React.render(<Root/>, document.createElement('div'));

let tree = {
    name,
    children: []
};

let tree = traverse(root, tree); // your component hierarchy by name in a tree

taken from this repo

Sign up to request clarification or add additional context in comments.

Comments

0

If you don't want vertical composition, you can use a ref.
Otherwise they be references passed as props in the case of descendants accessing ancestor components, or held in scope in the case of ancestors accessing descendants components.

https://facebook.github.io/react/docs/more-about-refs.html Refs in principle allow more horizontal composition, but really if you are doing a lot of this you might want to think about your data model, and implementation of something like Flux / unidirectional data flow. That's a pointer from the docs actually ; they recommend you to think carefully about data structure & state. (see https://facebook.github.io/react/docs/more-about-refs.html#cautions)

In your case I would recommend having a function passed as prop to all components where they can trigger a state change to set most recently viewed component. You just need also to pass them a unique id as prop.

[...] Assuming you have control over the programmatic response of components to being selected, you should pass all components a common handler function which resides in a common ancestor component. It would take as argument an index which would uniquely identify the component. That function would update state and React would issue a new Render cycle.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.