На самом деле происходит, когда вы устанавливаете 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
имеет значение true, и отображал бы некоторый «счетчик», если он есть ... например:
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>
)
}
}
Но поскольку мы не согласны с этим шаблоном UX, вот еще одно предложение:
Отслеживайте предыдущие результаты и продолжайте показывать их, пока новое изменение состояния не произойдет с новыми результатами:
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>
)
}
}