状态更改后,React组件不会重新呈现

时间:2019-04-06 01:05:09

标签: javascript reactjs rendering carousel

我正在从父容器中接收道具,并且在子组件中使用轮播显示图像。我的代码如下:

import React, { Component } from "react";
import ReactDOM from "react-dom";
import style from './ReactSlick.less';
import Carousel from 'nuka-carousel';

export default class ReactSlick extends Component {

  constructor(props) {
    super(props);
    this.state = {
      slides:this.props.pictureArray,
    };
  }}

renderImages() {
 return this.state.slides.map(slide => {
    return (
      <div  key={slide._id}><img src = {slide.image} /></div>
    );
  }, this);
}

return (
  <div className = {style.container}>
      <Carousel autoplay={true}>
        {this.renderImages()}
      </Carousel>
  </div>
);
}}

我基本上已经尝试了所有可以想到的方法,包括在componentDidMount中初始化内容。使用条件渲染来检查数组的长度,并且仅在存在任何内容时显示。图片数组是一个数组,其中包含要在轮播中显示的具有ID的图像。我从这样的父容器中获取它:

getImage= (key)=> {
            let {getImage} = this.props;
            let codeArray = [];
        for (let i = 0; i < getImage._id.length; i++) {
             api(getImage._id[i])
            .then(res => codeArray.push(res)),
            (error => console.log(error));}

        return (
            <Bubble
                key={key}
                side="left"
                onImageClick={this.handleLogoClick}>
                <ReactSlick pictureArray={codeArray} />
                </Bubble>
        );
    }

当它进入子组件时,数据已经存在,我也通过在构造函数中将其注销对它进行了双重检查。我尝试将API放入componentDidMount并在子组件中设置状态,但这也不起作用。

我已经测试了我从本地API获取的相同数据,并且似乎可以通过JSON进行工作,但是当我从远程服务器上获取数据时却无法工作。它唯一显示服务器中数据的时间是当我对代码进行更改并且它主动重新加载时,以某种方式可以看到该数据,但不是第一次。

我认为该组件不会重新渲染。是否可以对子组件进行强制刷新以使其正常工作?我已经读过答案,说setState调用时它会自动触发重新渲染,但对我而言似乎没有任何作用。

2 个答案:

答案 0 :(得分:1)

问题是您针对asynchronous代码进行迭代的方式。由于您尝试通过异步api调用在循环内填充codeArray,因此不能使用for loop,否则getImage不会等待api调用解决,因此codeArray为空时立即返回。因此,请使用可以与.map配合使用的其他类型的迭代器,例如async code

这可能对您有帮助,请查看以下内容:Using async/await with a forEach loop

/* So this doesn't work */
for (let i = 0; i < getImage._id.length; i++) {
  api(getImage._id[i]).then(res => codeArray.push(res)), (error => console.log(error));
}



/* Need to find a way to wait for all `api(getImage._id[i]).then` calls
   to finish first, only then should `getImage()` return.
   And also take not I am placing `codeArray` in the parent's state */


async getImage () {
  let codeArray = []; // just set the scope using let

  await Promise.all(this.props.images.map(async (image) => {
    codeArray = await api(getImage._id[i]);
  }));

  this.setState({ codeArray })
}

我建议在已安装的组件中调用getImage

async componentDidMount() {
  await this.getImage();
}

最后在您的render方法中: <ReactSlick pictureArray={this.state.codeArray} />

/* also set your component state codeArray as an empty array to be safe */

P.S:我假设images已经从父母的道具中设置了(但是它也可以处于状态)。如果images有10个项目,并且api()调用需要1秒才能完成,因此getImage()将花费10 seconds左右,然后调用setState或更新您的组件(以及子ReactSlick

我希望这对您有帮助

答案 1 :(得分:0)

您已有props,为什么要使用state进行循环?为此的另一种解决方案是使用self-route。因此,只要API成功获取数据即可。