反应:状态更新时UI闪烁

Tra*_* S. 5 javascript reactjs react-apollo apollo-client react-hooks

我有一个组件,用于显示从Spotify API返回的搜索数据。但是,每次更新状态时,UI都会闪烁:

在此处输入图片说明 输入:

            <DebounceInput
                debounceTimeout={300}
                onChange={handleChange}
            />
Run Code Online (Sandbox Code Playgroud)

钩:

const [searchResults, setSearchResults] = useState(null)
Run Code Online (Sandbox Code Playgroud)

带Apollo的API调用:

 const searchSpotify = async (query) => {
    const result = await props.client.query({
        query: SearchTracks,
        variables: {
            query
        }
    })
    const tracks = result.data.searchedTracks
    setSearchResults(tracks)
}
Run Code Online (Sandbox Code Playgroud)

渲染:

        {searchResults &&
            <div className="search-results">
                    {searchResults.map((song) => (
                            <SongInfo key={song.id} {...song} />
                    ))}
            </div>
        }
Run Code Online (Sandbox Code Playgroud)

我注意到它仅在第一次加载时发生。例如,如果我再次键入查询,它将显示而不会闪烁。有没有更好的方法来实现此目的,以使UI不会闪烁?

aba*_*yan 7

下面是导致闪烁的帧。我认为正在发生的事情是图像加载需要一些时间。当他们装载物品时,物品的高度会降低。您应该确保SongInfo布局不依赖于图像是否已加载。

图像未加载 - 项目已折叠:

在此输入图像描述

图片已加载:

在此输入图像描述


var*_*ons 5

我认为发生的事情是您在每次击键时执行搜索查询,这导致了奇怪的行为。

使用 lodash debounce 可以避免对每个击键进行搜索。这应该可以解决闪烁问题。(此外,添加加载状态也会有所帮助)

去抖组件示例

import React, {Component} from 'react'
import { debounce } from 'lodash'

class TableSearch extends Component {

  //********************************************/

  constructor(props){
    super(props)

    this.state = {
        value: props.value
    }

    this.changeSearch = debounce(this.props.changeSearch, 250)
  }

  //********************************************/

  handleChange = (e) => {
    const val = e.target.value

    this.setState({ value: val }, () => {
      this.changeSearch(val)
    })
  }

  //********************************************/

  render() {

    return (
        <input
            onChange = {this.handleChange}
            value = {this.props.value}
        />
    )
  }

  //********************************************/

}
Run Code Online (Sandbox Code Playgroud)