Реактивный компонент не рендерится после изменения состояния - PullRequest
0 голосов
/ 06 апреля 2019

Я получаю реквизиты из родительского контейнера и использую карусель в дочернем компоненте для показа изображений.Мой код выглядит так:

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.Использование условного рендеринга для проверки длины массива и отображения только при наличии чего-либо.Массив picture - это массив, содержащий изображения с идентификаторами, которые я хочу отобразить в карусели.Я получаю его из родительского контейнера следующим образом:

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 ]

1 голос
/ 06 апреля 2019

Проблема в том, как вы выполняете итерацию кода asynchronous. Поскольку вы пытаетесь заполнить codeArray внутри цикла из асинхронного вызова API , вы не можете использовать for loop, в противном случае getImage не будет ждать разрешения вашего вызова API и, следовательно, немедленно вернется, пока codeArray все еще пуст. Поэтому используйте другие типы итераторов, такие как .map, которые могут работать с async code.

Это может помочь, проверьте это: Использование async / await с циклом forEach

/* 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 в компоненте mount:

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)

Надеюсь, это поможет

0 голосов
/ 06 апреля 2019

У вас уже есть props, зачем вам использовать state для итерации цикла?Другое решение для этого использует self-route.Поэтому всякий раз, когда API успешно извлекал данные.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...