我正在为我的React项目添加流程。我按照流程反应参考部分中的说明进行操作。
我的问题是我在多个位置使用ref对象,所以如果我将它定义为可选,我会得到一个错误访问它,否则我从ref本身得到一个错误,因为它最初为null。
有没有一个解决方案,每次我想使用ref时都不需要检查?我可以告诉流程不对refs运行检查吗?
这里有一个简短的片段来解释我在做什么:
class AudioPlayer extends Component<Props> {
player: ?HTMLAudioElement;
componentWillUpdate(nextProps) {
if (nextProps.duration && this.player.currentTime >= nextProps.duration) {
this.reset();
}
}
render() {
const { src } = this.props;
return (
<audio
className="track-audio"
ref={audio => (this.player = audio)}
loop
onTimeUpdate={this.handleTimeUpdate}
onLoadedMetadata={this.handleLoadMetadata}
>
<source src={src} />
</audio>
);
}
}
考虑到我不想删除引用,除了检查!isEmpty(this.player)
在哪里需要它之外,还有一个简单的解决方案吗?
答案 0 :(得分:0)
The docs描述了为什么你应该使用一个可选的。你也可以像下面一样定义它(没有真正的优势,除非你发现它一目了然更容易理解):
class AudioPlayer extends Component<Props> {
player: ?React.ElementRef<'audio'>;
// ...rest
}
如果你发现这很烦人(我完全明白,相信我),你可以做一些不同的事情(我只列出我能想到的那些):
将该函数作为回调检查(不是超级优雅,但它完成了工作)
class AudioPlayer extends Component<Props> {
checkForPlayer(callback) {
if (this.player) {
return callback()
}
}
componentWillUpdate(nextProps) {
this.checkForPlayer(() => {
if (nextProps.duration && this.player.currentTime >= nextProps.duration) {
this.reset();
}
})
}
}
你可以做类似的事情,但有点像装饰者(我个人认为这一般来说更难阅读,但这是一个选择)
class AudioPlayer extends Component<Props> {
checkForPlayer(callback) {
return (...args) =>
if (this.player) {
return callback(...args)
}
}
}
componentWillUpdate: this.checkForPlayer(nextProps => {
if (nextProps.duration && this.player.currentTime >= nextProps.duration) {
this.reset();
}
})
}
每当您访问this.player
(get(this.player, 'currentTime')
)上的属性时,您都可以使用类似于(或完全)lodash.get
的效用函数。除非你认为你会从以前的选项中看到很大的好处,否则我可能会坚持这样的事情。您会很快习惯语法,并且不需要额外的工作。你甚至可以做这样的事情(在查看我的答案后,这几乎是事后的想法。它可能并不比使用普通的效用函数更好):
class AudioPlayer extends Component<Props> {
playerProp(prop) {
return this.player ? this.player[prop] : null
}
componentWillUpdate: this.checkForPlayer(nextProps => {
if (nextProps.duration && this.playerProp('currentTime') >= nextProps.duration) {
this.reset();
}
})
}