我正在向现有项目添加Flow。我的普通道具类型检查工作得很好,但我无法弄清楚为什么我的搜索输入ref函数存在问题。我已经按照Flow文档并使用searchInput: ?HTMLInputElement
设置了一行,但这只会导致更多错误。这是我正在使用的代码的精简版本,其中包含所有相关的this.searchInput
引用:
// @flow
import React, { Component } from 'react'
class DataTable extends Component {
searchInput: ?HTMLInputElement
loadNextPage = () => {
const isFetching = this.props.isFetching
const number = this.props.paginationNumber
const links = this.props.links
if (!isFetching && links.next && this.searchInput.value === '') {
this.props.fetchData(number + 1, 10)
}
}
handleKeyDown = e => {
if (e.keyCode === 13) {
this.search(e.target.value)
}
}
search = text => {
this.props.searchData(1, 1, text)
this.forceUpdate()
}
handleSearch = () => {
this.search(this.searchInput.value)
}
handleClear = () => {
this.clearSearch()
}
clearSearch = () => {
const number = this.props.paginationNumber
if (this.searchInput.value !== '') {
this.searchInput.value = ''
this.props.clearSearch()
this.props.fetchData(number + 1, 10)
}
}
render() {
<Flex justify="center">
<Box>
<input
type="search"
ref={ input => this.searchInput = input }
onKeyDown={ this.handleKeyDown }
/>
<PrimaryButton
onClick={ this.handleSearch }>
SEARCH
</PrimaryButton>
<PrimaryButton
onClick={ this.handleClear }>
CLEAR
</PrimaryButton>
</Box>
</Flex>
)
}
这会对this.searchInput.value
的每次引用产生以下错误:
this.search(this.searchInput.value)
^^^^^ property `value`. Property cannot be accessed on possibly null value
this.search(this.searchInput.value)
^^^^^^^^^^^^^^^^ null or undefined
我也尝试从?
删除?HTMLInputElement
,但这给了我这个错误:
ref={ input => this.searchInput = input }
^^^^^ null. This type is incompatible with
ref={ input => this.searchInput = input }
^^^^^^^^^^^^^^^^ HTMLInputElement
任何想法如何让这些类型检查通过?
答案 0 :(得分:3)
问题是您是否尝试访问value
某些类型的内容。原因就在同一页上:
?
中的?HTMLButtonElement
非常重要。在上面的例子中ref
的第一个参数将是HTMLButtonElement | null
,就像React一样 当组件卸载时,使用null调用您的ref
回调。也, 在React拥有之前,button
上的MyComponent
属性不会被设置 完成渲染。在此之前,您的button
引用将不确定。 保护自己免受这些情况的影响并使用?
(如?HTMLButtonElement
)保护自己免受错误。
看起来有点矫枉过正,但绝对可以让你免受随机问题的困扰。您应该进行以下更改:
class DataTable extends Component {
searchInput: ?HTMLInputElement
loadNextPage = () => {
const isFetching = this.props.isFetching
const number = this.props.paginationNumber
const links = this.props.links
if (!isFetching && links.next && this.searchInput && this.searchInput.value === '') {
this.props.fetchData(number + 1, 10)
}
}
handleSearch = () => {
if (!this.searchInput) {
return
}
this.search(this.searchInput.value)
}
clearSearch = () => {
const number = this.props.paginationNumber;
if (this.searchInput && this.searchInput.value !== '') {
this.searchInput.value = ''
this.props.clearSearch()
this.props.fetchData(number + 1, 10)
}
}
// ...etc
}
您尝试访问某个属性null
的属性,这就是您查看错误的原因。你只需要检查是否存在。
答案 1 :(得分:0)
我无法保证为什么会发生这种情况,但我认为这是因为ref是因为在调用ref回调之前正在执行流,因此在第一次渲染/挂载时ref等于null。
解决这个问题的一种方法是:
searchInput: any
这不是最好的解决方案,因为您并没有准确指定类型,但您也可以尝试做类似的事情
searchInput: HTMLInputElement | null
无法保证第二种方法对您有用。有时我觉得使用任何类型是不可避免的,只是为了节省很多时间。我强烈建议尽可能避免它......