Saeid Ostad
Saeid Ostad

Reputation: 727

React.createRef() not works

I create a code sandbox to test-out new react createRef api but ie seams something is wrong. I followed react doc but I couldn't figure out what's wrong. can anybody take a look at code please.

"react": "16.5.2",

"react-dom": "16.5.2",

Parent Component:

import React, { Component } from "react";
import ChildComponent from "./ChildComponent";

export default class ParentComponent extends Component {
  constructor(props) {
    super(props);
    this.myRef = React.createRef();
  }
  render() {
    const node = this.myRef.current;
    return (
      <React.Fragment>
        <ChildComponent ref={this.myRef} />
        <button
          onClick={() => {
            console.log(node);
          }}
        >
          Run Me
        </button>
      </React.Fragment>
    );
  }
}

Child Component:

import React, { Component } from "react";

export default class MyComponent extends Component {
  state = {
    message: "nothing!"
  };
  SayHi = () => {
    this.setState({ message: "Hi From Parent" });
  };
  render() {
    const { message } = this.state;
    return <div>Message: {message}</div>;
  }
}

Upvotes: 1

Views: 10803

Answers (2)

Nikhil
Nikhil

Reputation: 119

I think you are trying to run SayHi() method of child component upon clicking of button, In your parent component's render you need to remove const node = this.myRef.current and the onClick method will be as follows

onClick={() => { this.myRef.current.SayHi(); }}

this will invoke SayHi() method of child component.

Upvotes: 1

Dacre Denny
Dacre Denny

Reputation: 30360

This is likely due to your ref not being fully initialised after the first render, meaning that when onClick is invoked, your're technically "logging" an cached copy of an uninitialised value.

Consider making the following change to cause the initialised and "current" ref to be accessed during the onClick event:

export default class ParentComponent extends Component {
  constructor(props) {
    super(props);
    this.myRef = React.createRef();
  }
  render() {
    // const node = this.myRef.current; <-- Remove this
    return (
      <React.Fragment>
        <ChildComponent ref={this.myRef} />
        <button
          onClick={() => {
            // Move to here, causes the current ref to be accessed during onClick
            const node = this.myRef.current;
            console.log(node);
          }}
        >
          Run Me
        </button>
      </React.Fragment>
    );
  }
}

Hope this helps!

Upvotes: 4

Related Questions