Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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

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

like image 399
horgen Avatar asked Sep 20 '18 11:09

horgen


People also ask

How do you get the DOM element from the ref React?

We access a DOM element using the current property of a reference created with the React. createRef() function. React will update this property with an actual DOM element after render and before update events. That means that we can access the DOM element in componentDidMount and componentDidUpdate functions.

How do you access the DOM element in a React functional component?

Accessing DOM nodes in the same React component. To create a reference to a DOM node in a component we can do it either using the useRef() hook, which for most cases is the easier and best approach, or using the callback ref pattern which gives you more control when refs are set and unset.

What is React createRef ()?

This method is used to access any DOM element in a component and it returns a mutable ref object which will be persisted as long as the component is placed in the DOM. If we pass a ref object to any DOM element, then the. current property to the corresponding DOM node elements will be added whenever the node changes.

What is the difference between useRef () used for function components and createRef () for class components?

useRef: The useRef is a hook that uses the same ref throughout. It saves its value between re-renders in a functional component and doesn't create a new instance of the ref for every re-render. It persists the existing ref between re-renders. createRef: The createRef is a function that creates a new ref every time.


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!)

like image 92
Rose Robertson Avatar answered Nov 15 '22 05:11

Rose Robertson