搜索栏过滤 table 结果 React 超时
Search bar to filter table results in React with timeout
我正在使用语义 React UI Search 来过滤 React 中数据 table 组件的结果。 table如果搜索为空则显示所有数据,如果搜索不为空则不显示任何数据或匹配结果。我的问题是,在您进行搜索时,"No data" 总是快速闪烁。
原始搜索代码将结果显示为下拉列表,但我对其进行了修改以修改table。代码如下。
class Page extends Component {
resetComponent = () => this.setState({ isLoading: false, results: [], value: '' })
handleSearchChange = (e, { value }) => {
this.setState({ isLoading: true, value })
setTimeout(() => {
if (this.state.value.length < 1) return this.resetComponent()
const re = new RegExp(_.escapeRegExp(this.state.value), 'i')
const isMatch = result => re.test(result.name)
this.setState({
isLoading: false,
results: _.filter(this.props.users, isMatch),
})
}, 200)
}
render() {
const { users } = this.props
const { value, results } = this.state
const dataToShow = _.isEmpty(results) && !value ? users : results
return (
<Container>
<Search
open={false}
loading={isLoading}
onSearchChange={_.debounce(this.handleSearchChange, 500, { leading: true })}
value={value}
{...this.props}
/>
<Table data={dataToShow} />
</Container>
)
}
}
我认为 const dataToShow = _.isEmpty(results) && !value ? users : results
行是导致它闪烁的原因,但我不知道如果没有匹配则不显示任何结果,或者如果为空则显示所有结果。
如何让这个 timeout/debounce 在 table 上正常工作?
如果我这样做 <Table data={results} />
去抖会起作用,但是 table 不会在初始加载时显示所有数据。
实际发生的情况是,当您设置 this.setState({ isLoading: true, value })
时,组件将在您更改状态后重新呈现。发生这种情况时,这一行:
const dataToShow = _.isEmpty(results) && !value ? users : results
实际上会显示 results
- 因为尽管结果为空,但您确实输入了一个值。这就是为什么你得到“无数据”的原因,因为你绑定到结果但它们是空的。
在那里试试这个:
const dataToShow = _.isEmpty(results) && !value ? users : this.state.isLoading ? users : results
它应该会在输入值时继续显示 users
,加载完成后它应该会更改为结果。
然而问题是(这就是为什么我建议使用微调器的简单方法)现在你会显示结果......然后在新的搜索中你会回到用户然后再次回到结果时加载完成。
我根本不会显示 <Table>
,而 this.state.isLoading
是真的,如果是,我会显示一些 "spinner" ... 例如:
class Page extends Component {
resetComponent = () => this.setState({ isLoading: false, results: [], value: '' })
handleSearchChange = (e, { value }) => {
setTimeout(() => {
this.setState({ isLoading: true, value })
if (this.state.value.length < 1) return this.resetComponent()
const re = new RegExp(_.escapeRegExp(this.state.value), 'i')
const isMatch = result => re.test(result.name)
this.setState({
isLoading: false,
results: _.filter(this.props.users, isMatch),
})
}, 200)
}
render() {
const { users } = this.props
const { value, results } = this.state
const dataToShow = _.isEmpty(results) && !value ? users : results
return (
<Container>
<Search
open={false}
loading={isLoading}
onSearchChange={_.debounce(this.handleSearchChange, 500, { leading: true })}
value={value}
{...this.props}
/>
{this.state.isLoading && <Spinner />}
{!this.state.isLoading && <Table data={dataToShow} />}
</Container>
)
}
}
但由于我们不同意用户体验模式,这里是另一个建议:
跟踪以前的结果并继续显示它们,直到新结果发生新的状态变化:
class Page extends Component {
constructor (props) {
super(props)
this.state = {
isLoading: false,
results: [],
oldResults: this.prop.users || [],
value: ''
}
}
resetComponent = () => this.setState({ isLoading: false, results: [], oldResults: this.prop.users || [], value: '' })
handleSearchChange = (e, { value }) => {
setTimeout(() => {
this.setState({ isLoading: true, value })
if (this.state.value.length < 1) return this.resetComponent()
const re = new RegExp(_.escapeRegExp(this.state.value), 'i')
const filteredResults = _.filter(this.props.users, result => re.test(result.name))
this.setState({
isLoading: false,
results: filteredResults,
oldResults: filteredResults
})
}, 200)
}
render() {
const { users } = this.props
const { value, results } = this.state
const dataToShow = (_.isEmpty(results) && !value) || this.state.isLoading ? oldResults : results
return (
<Container>
<Search
open={false}
loading={isLoading}
onSearchChange={_.debounce(this.handleSearchChange, 500, { leading: true })}
value={value}
{...this.props}
/>
<Table data={dataToShow} />
</Container>
)
}
}
我正在使用语义 React UI Search 来过滤 React 中数据 table 组件的结果。 table如果搜索为空则显示所有数据,如果搜索不为空则不显示任何数据或匹配结果。我的问题是,在您进行搜索时,"No data" 总是快速闪烁。
原始搜索代码将结果显示为下拉列表,但我对其进行了修改以修改table。代码如下。
class Page extends Component {
resetComponent = () => this.setState({ isLoading: false, results: [], value: '' })
handleSearchChange = (e, { value }) => {
this.setState({ isLoading: true, value })
setTimeout(() => {
if (this.state.value.length < 1) return this.resetComponent()
const re = new RegExp(_.escapeRegExp(this.state.value), 'i')
const isMatch = result => re.test(result.name)
this.setState({
isLoading: false,
results: _.filter(this.props.users, isMatch),
})
}, 200)
}
render() {
const { users } = this.props
const { value, results } = this.state
const dataToShow = _.isEmpty(results) && !value ? users : results
return (
<Container>
<Search
open={false}
loading={isLoading}
onSearchChange={_.debounce(this.handleSearchChange, 500, { leading: true })}
value={value}
{...this.props}
/>
<Table data={dataToShow} />
</Container>
)
}
}
我认为 const dataToShow = _.isEmpty(results) && !value ? users : results
行是导致它闪烁的原因,但我不知道如果没有匹配则不显示任何结果,或者如果为空则显示所有结果。
如何让这个 timeout/debounce 在 table 上正常工作?
如果我这样做 <Table data={results} />
去抖会起作用,但是 table 不会在初始加载时显示所有数据。
实际发生的情况是,当您设置 this.setState({ isLoading: true, value })
时,组件将在您更改状态后重新呈现。发生这种情况时,这一行:
const dataToShow = _.isEmpty(results) && !value ? users : results
实际上会显示 results
- 因为尽管结果为空,但您确实输入了一个值。这就是为什么你得到“无数据”的原因,因为你绑定到结果但它们是空的。
在那里试试这个:
const dataToShow = _.isEmpty(results) && !value ? users : this.state.isLoading ? users : results
它应该会在输入值时继续显示 users
,加载完成后它应该会更改为结果。
然而问题是(这就是为什么我建议使用微调器的简单方法)现在你会显示结果......然后在新的搜索中你会回到用户然后再次回到结果时加载完成。
我根本不会显示 <Table>
,而 this.state.isLoading
是真的,如果是,我会显示一些 "spinner" ... 例如:
class Page extends Component {
resetComponent = () => this.setState({ isLoading: false, results: [], value: '' })
handleSearchChange = (e, { value }) => {
setTimeout(() => {
this.setState({ isLoading: true, value })
if (this.state.value.length < 1) return this.resetComponent()
const re = new RegExp(_.escapeRegExp(this.state.value), 'i')
const isMatch = result => re.test(result.name)
this.setState({
isLoading: false,
results: _.filter(this.props.users, isMatch),
})
}, 200)
}
render() {
const { users } = this.props
const { value, results } = this.state
const dataToShow = _.isEmpty(results) && !value ? users : results
return (
<Container>
<Search
open={false}
loading={isLoading}
onSearchChange={_.debounce(this.handleSearchChange, 500, { leading: true })}
value={value}
{...this.props}
/>
{this.state.isLoading && <Spinner />}
{!this.state.isLoading && <Table data={dataToShow} />}
</Container>
)
}
}
但由于我们不同意用户体验模式,这里是另一个建议:
跟踪以前的结果并继续显示它们,直到新结果发生新的状态变化:
class Page extends Component {
constructor (props) {
super(props)
this.state = {
isLoading: false,
results: [],
oldResults: this.prop.users || [],
value: ''
}
}
resetComponent = () => this.setState({ isLoading: false, results: [], oldResults: this.prop.users || [], value: '' })
handleSearchChange = (e, { value }) => {
setTimeout(() => {
this.setState({ isLoading: true, value })
if (this.state.value.length < 1) return this.resetComponent()
const re = new RegExp(_.escapeRegExp(this.state.value), 'i')
const filteredResults = _.filter(this.props.users, result => re.test(result.name))
this.setState({
isLoading: false,
results: filteredResults,
oldResults: filteredResults
})
}, 200)
}
render() {
const { users } = this.props
const { value, results } = this.state
const dataToShow = (_.isEmpty(results) && !value) || this.state.isLoading ? oldResults : results
return (
<Container>
<Search
open={false}
loading={isLoading}
onSearchChange={_.debounce(this.handleSearchChange, 500, { leading: true })}
value={value}
{...this.props}
/>
<Table data={dataToShow} />
</Container>
)
}
}