Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

React ref returns a 'Connect' object instead of DOM

I'm trying to create dynamics refs for custom components created through the map function.

class PostsList extends Component {

  constructor(props) {
    super(props);
  }

  componentDidUpdate = () => {
    console.log(this.refs);
  }

  render() {
    let posts = this.props.posts || [];
    return (
        <div ref="test">
          {posts.map((post) => {
            return <Post post={post} key={post.id} ref={post.id}></Post>
          })}
        </div>
    );
  }

}

export default PostsList

the console.log returns the correct DOM node for refs.test but for the ones in the loop, it's returning a Connect Object. Screenshot

Can someone point me in the right direction?

like image 404
Andrew Park Avatar asked Jan 09 '17 18:01

Andrew Park


People also ask

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

In React we can access the DOM element using Refs. Refs provide a way to access DOM nodes or React elements created in the render method. Creating Refs: Refs are created using React. createRef() and attached to React elements via the ref attribute.

What can I use instead of REF IN React?

Instead of passing a ref attribute created by createRef() , you pass a function. The function receives the React component instance or HTML DOM element as its argument, which can be stored and accessed elsewhere.

Can you pass ref to component?

The second ref argument only exists when you define a component with React.forwardRef call. Regular function or class components don't receive the ref argument, and ref is not available in props either. Ref forwarding is not limited to DOM components. You can forward refs to class component instances, too.

How do you pass ref to the functional component?

To create a ref in a functional component we use the useRef() hook which returns a mutable object with a . current property set to the initialValue we passed to the hook. This returned object will persist for the full lifetime of the component. Thus, throughout all of its re-rendering and until it unmounts.


2 Answers

It seems like Post is a connected component, while you actually want the wrapped one.

react-redux ≥ 6.0.0

Connect with forwardRef: true

connect(null, null, null, { forwardRef: true })(Post);

then add a ref normally:

ref={ref => this.<id> = ref}

From the docs:

If {forwardRef : true} has been passed to connect, adding a ref to the connected wrapper component will actually return the instance of the wrapped component.




react-redux < 6

Connect with withRef: true

connect(null, null, null, { withRef: true })(Post);

then use getWrappedInstance() to get the underlying connected component:

this.refs[<id>].getWrappedInstance()

From the docs:

[withRef] (Boolean): If true, stores a ref to the wrapped component instance and makes it available via getWrappedInstance() method. Default value: false

like image 147
Or B Avatar answered Sep 20 '22 16:09

Or B


An alternative way to do this would be to use some other prop name (other than ref). For example:

<Post
  ...
  innerRef={(node) => { this.myRef = node; }}
/>

This also works if you're using a library like styled-components or emotion

like image 20
Divyanshu Maithani Avatar answered Sep 19 '22 16:09

Divyanshu Maithani