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
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.
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.
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.
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.
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
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!)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With