Reputation: 63
In order to allow my parent component
(JsonFetcher
) to access values from my child component
(Display
), I tried using createRef()
API that just came of this patch 16.3
Following the "Adding a Ref to a class Component" example in this document, here's what I tried in my code:
class JsonFetcher extends Component {
constructor(props) {
super(props);
this.child = React.createRef();
this.state = {
data: [],
}
}
componentDidMount() {
this.updateContent(this.props.mainUrl)
}
updateContent(mainUrl){
fetch(mainUrl)
.then((responseJsonAnyUrl) => responseJsonAnyUrl.json())
.then((responseJsonAnyUrl) => {
this.setState({
mainUrl: mainUrl,
jsonObject: responseJsonAnyUrl
},
function () {
this.timeout = setTimeout(
function(){
//let ind = this.child.current.getCurrentIndex
//tyring to get values from child...
//if index === length-1
this.updateContent(mainUrl)
//else
//retry this function in 5 seconds
//
}.bind(this, mainUrl)
,
20000)
}.bind(this))
})
}
interpretJson() {
/*
*some code
*/
return(
<Display content={contentListArray} ref={this.child}/>
)
}
render() {
if(this.state.jsonObject){
return (
<div>
<div> {this.interpretJson()} </div>
</div>
)
}else
return(
null
)
}
}
So, I created the ref
in the constructor, linked it to the child component
Display
in the end of interpretJson()
method and then i'm trying to use the the child method in my timeOut()
function. However I get the following error:
"TypeError: Cannot read property 'getCurrentIndex' of null "
What am I doing wrong that's not letting me call the child methods so I can simulate the pseudo-code I have commented?
(Edit) Notes:
My child component Display
is not a stateless component, it's a
class.
I already tried calling <Display>
in the render instead but the
problem remained.
Upvotes: 6
Views: 9249
Reputation: 3681
I also encountered this issue (I'm using typescript)
private modal = React.createRef<HTMLDivElement>()
// ...
public componentDidMount() {
console.log(this.modal)
}
// ...
public render() {
// ...
<div ref={this.modal} className="modal fade"
// ...
Output. From start is null, then is populated after some little time:
The problem was that in render method I exited early, and ref code was not reached
public render() {
const { data } = this.state
// here we return early, ref bellow is not reached
// and in componentDidmount we can't rely on this.modal.current
// this.modal.current will be populated only if data is not null
if (data === null) { return null }
return (
<div ref={this.modal} className="modal fade"
// ...
same problem in example in bellow example
example: https://codesandbox.io/s/ymvxj5pqmx
Upvotes: 0
Reputation: 9368
Use arrow function to bind this method to the class. This way, the this in this.child
will bind to the class component
interpretJson = () => {
/*
*some code
*/
return(
<Display content={contentListArray} ref={this.child}/>
)
}
if the above answer doesn't work then do this
constructor(props) {
super(props);
this.interpretJson = this.interpretJson.bind(this);//bind function to class
this.child = React.createRef();
this.state = {
data: [],
}
}
interpretJson() {
/*
*some code
*/
return(
<Display content={contentListArray} ref={this.child}/>
)
}
Upvotes: 0