admin管理员组

文章数量:1327100

I've a React component. Some elements will be inserted through the children. Some of these elements will have a specific classname. How can I get a list of these DOM nodes in my outermost Component?

<MyComponent>
  <div classname="snap"/>
  <p></p>
  <div classname="snap"/>
  <p></p>
  <div classname="snap"/>
</MyComponent>

What I want to know is how many elements with the classname "snap" are inserted in my component.

I've a React component. Some elements will be inserted through the children. Some of these elements will have a specific classname. How can I get a list of these DOM nodes in my outermost Component?

<MyComponent>
  <div classname="snap"/>
  <p></p>
  <div classname="snap"/>
  <p></p>
  <div classname="snap"/>
</MyComponent>

What I want to know is how many elements with the classname "snap" are inserted in my component.

Share Improve this question asked Mar 8, 2017 at 8:14 wvpwvp 1,1745 gold badges15 silver badges30 bronze badges 1
  • you want to know how many snaps are in MyComponent from inside MyComponent? – Dhiraj Commented Mar 8, 2017 at 8:31
Add a comment  | 

4 Answers 4

Reset to default 17

You can achieve it, via findDOMNode of react-dom, like below:

ReactDOM.findDOMNode(<instance-of-outermost-component>).getElementsByClassName('snap') // Returns the elements

If you need the count,

ReactDOM.findDOMNode(<instance-of-outermost-component>).getElementsByClassName('snap').length

You can use ReactDOM.findDOMNode. Even though the documentation encourage using ref, let's see how it works:

findDOMNode()

ReactDOM.findDOMNode(component)

If this component has been mounted into the DOM, this returns the corresponding native browser DOM element. This method is useful for reading values out of the DOM, such as form field values and performing DOM measurements. In most cases, you can attach a ref to the DOM node and avoid using findDOMNode at all.

When a component renders to null or false, findDOMNode returns null. When a component renders to a string, findDOMNode returns a text DOM node containing that value. As of React 16, a component may return a fragment with multiple children, in which case findDOMNode will return the DOM node corresponding to the first non-empty child.


Note: findDOMNode is an escape hatch used to access the underlying DOM node. In most cases, use of this escape hatch is discouraged because it pierces the component abstraction. findDOMNode only works on mounted components (that is, components that have been placed in the DOM). If you try to call this on a component that has not been mounted yet (like calling findDOMNode() in render() on a component that has yet to be created) an exception will be thrown. findDOMNode cannot be used on functional components.

Also let's look at the ref, which is recommended:

Adding a Ref to a Class Component

When the ref attribute is used on a custom component declared as a class, the ref callback receives the mounted instance of the component as its argument. For example, if we wanted to wrap the CustomTextInput above to simulate it being clicked immediately after mounting:

class AutoFocusTextInput extends React.Component {
    componentDidMount() {
      this.textInput.focusTextInput();
    }

    render() {
      return (
        <CustomTextInput
          ref={(input) => { this.textInput = input; }} />
      );
    }
}

Note that this only works if CustomTextInput is declared as a class:

class CustomTextInput extends React.Component {
  // ...
}

I had a similar issue where document.getElementsByClassName was not returning what I needed. I found that using document.querySelectorAll did the trick. In terms of the code in question:

const elements = document.querySelectorAll(["classname=snap"])
const length = elements.length

Why does this work? As per https://developer.mozilla.org/en-US/docs/Web/API/Document/querySelector, document.querySelector will return the first element within the document that matches the specified selector. Therefore, document.querySelectorAll will return all elements within the document that matches the specified selector.

I know this post is quite old but hopefully the above can help someone in a similar position to me. I came to the conclusion that document.getElementsByClassName probably doesn't work with React because according to https://developer.mozilla.org/en-US/docs/Web/API/Document/getElementsByClassName this is applicable to elements that have a class as opposed to a className.

Yoy can also use this.props.children to get number of child nodes with given class:

let snapCount = React.Children.toArray(this.props.children).filter((item) => item.props.className === 'snap').length;

本文标签: javascriptReactJSfind elements by classname in a React ComponentStack Overflow