Reputation: 727
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
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
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