How to get the DOM node from a Class Component ref with the React.createRef() API

Viewed 3727

I have these two components:

import { findDOMNode } from 'react-dom';

class Items extends Component {
    constructor(props) {
        super(props);
        this.ref = React.createRef();
        this.selectedItemRef = React.createRef();
    }

    componentDidMount() {
        if (this.props.selectedItem) {
            this.scrollToItem();
        }
    }

    componentWillReceiveProps(nextProps) {
        if (this.props.selectedItem !== nextProps.selectedItem) {
            this.scrollToItem();
        }
    }

    scrollToItem() {
        const itemsRef = this.ref.current;
        const itemRef = findDOMNode(this.selectedItemRef.current);

        // Do scroll stuff here
    }

    render() {
        return (
            <div ref={this.ref}>
                {this.props.items.map((item, index) => {
                    const itemProps = {
                        onClick: () => this.props.setSelectedItem(item.id)
                    };

                    if (item.id === this.props.selectedItem) {
                        itemProps.ref = this.selectedItemRef;
                    }

                    return <Item {...itemProps} />;
                })}
            </div>
        );
    }
}

Items.propTypes = {
    items: PropTypes.array,
    selectedItem: PropTypes.number,
    setSelectedItem: PropTypes.func
};

and

class Item extends Component {
    render() {
        return (
            <div onClick={() => this.props.onClick()}>item</div>
        );
    }
}

Item.propTypes = {
    onClick: PropTypes.func
};

What is the proper way to get the DOM node of this.selectedItemRef in Items::scrollToItem()?

The React docs discourage the use of findDOMNode(), but is there any other way? Should I create the ref in Item instead? If so, how do I access the ref in Items::componentDidMount()?

Thanks

1 Answers

I think what you want is current e.g. this.selectedItemRef.current

It's documented on an example on this page: https://reactjs.org/docs/refs-and-the-dom.html

enter image description here

And just to be safe I also tried it out on a js fiddle and it works as expected! https://jsfiddle.net/n5u2wwjg/195724/

If you want to get the DOM node for a React Component I think the preferred way of dealing with this is to get the child component to do the heavy lifting. So if you want to call focus on an input inside a component, for example, you’d get the component to set up the ref and call the method on the component, eg

this.myComponentRef.focusInput()

and then the componentRef would have a method called focusInput that then calls focus on the input.

If you don't want to do this then you can hack around using findDOMNode and I suppose that's why it's discouraged!

(Edited because I realized after answering you already knew about current and wanted to know about react components. Super sorry about that!)

Related