setState正在更新数组中所有元素的css属性

时间:2018-02-19 10:22:41

标签: javascript reactjs

我通过数组映射并为数组的每个元素创建<li>元素。每个<img>元素中还有一个<li>,其中display属性的值取决于isDownloading状态对象。

问题:

每当我点击<li>元素时,图片就会显示所有<li>元素,而不是特定的<li>元素。

代码:

...
constructor() {
  super()
  this.state = {data: null, isDownloading: null}
}

componentDidMount() {
  ...
  //array of data from api call
  this.setState({data: dataArray})
}

generateList = (data) => {
  const listElement = data.map((info, i) => {
    return (
      <li onClick={() => this.setState({isDownloading: true})} key={i}>Download<img style={{display: this.state.isDownloading ? 'inline-block' : 'none'}} src='loader.png' /></li>
    )
  }
  return listElement
}

render() {
  return (
    <div>
      <ul>
        {this.generateList(this.state.data)} //renders 10 li elements
      </ul>
    </div>
  )
}
...

1 个答案:

答案 0 :(得分:2)

这是因为每个 img你这样做:

style={{display: this.state.isDownloading ? 'inline-block' : 'none'}}

您正在为每个图像引用相同的状态。如果this.state.isDownloading 每个图片的样式将是:{ 'inline-block'},因为this.state.isDownloading为true。

现在,为每个元素显示一个加载器的一种方法是更新您的状态,以便您知道是否正在进行下载(isDownloading)以及它所引用的img。所以你必须跟踪两件事:

  • 正在下载?
  • 哪一个正在下载?

你可以通过更新你的onClick&#39;功能,我们可以举例说明&#39; key&#39;道具作为参数,以便我们知道正在下载哪个李:

<li onClick={() => this.setState({ isDownloading: true, keyItemBeingDownloaded: key})/>

现在你可以更新你的风格条件:

this.state.isDownloading && key === this.state.keyItemBeingDownloaded

现在, if isDownloading&amp;&amp; 如果正在下载的项目键对应于循环中的项目键,则显示加载程序。