I'm using reference of a DOM element with React, but I can't find a way to avoid flow telling me that the ref could be null even if i've explicitly checked right above.
Example here: http://bit.ly/2n6z8jB
This seem to only happen when calling a function on the ref:
[...]
componentDidMount() {
if (!this.refVideo) return;
this.refVideo.src = 'http://example.fr/video.mp3';
this.refVideo.load();
this.refVideo.play(); // This does not work, refVideo may be null ?
}
However doing this work:
componentDidMount() {
if (!this.refVideo) return;
this.refVideo.src = 'http://example.fr/video.mp3';
this.refVideo.load();
this.refVideo && this.refVideo.play(); // This work, but why don't I've to do the same of the line above ?
}
I'm having the same problem with Flow.
I'm checking my variable if it could be string or null and it returns an Error that the type is incompatible with the expected param type.
export const getAuthenticatedUser = () => {
const user: ?string = localStorage.getItem('user');
return isNil(user) ? null : JSON.parse(user); // [flow] null or undefined (This type is incompatible with the expected param type of string)
};
thx
@yadomi Your problem is due to refinement invalidation, that is that flow considers this.refVideo.load(); might make your call check invalid :/
@Tarektouati This seems to be another problem, it's that flow doesn't know that isNil refines user to a string. Doing a manual checks work return typeof user !== 'string' ? null : JSON.parse(user);.
@AugustinLF thanks ! You seem to be right because when I do this (as the doc says), I don't have any errors.
[...]
componentDidMount() {
if (!this.refVideo) return;
const video = this.refVideo;
video.src = 'http://example.fr/video.mp3';
video.load();
video.play();
}
This seems much like a hack to me than a real solution.
Is this the right way to do it or should I explicitly check this.refVideo on every function call ?
Thanks :)
Using a helper function is probably the way that looks the nicest. But I don't think you can do much cleaner than that :/
type Video = {src: string, load: Function, play: Function}
class stuff extends React.Component {
refVideo: ?Video
runVideo(video: Video) {
video.src = 'http://example.fr/video.mp3';
video.load();
video.play();
}
componentDidMount() {
if (!this.refVideo) return;
this.runVideo(this.refVideo);
}
}
@AugustinLF Thank for your help, that make sense
Most helpful comment
Using a helper function is probably the way that looks the nicest. But I don't think you can do much cleaner than that :/