javascript - React component doesn't re-render after state change - Stack Overflow

I am receiving props from a parent container and I am using a Carousel in the child ponent to show imag

I am receiving props from a parent container and I am using a Carousel in the child ponent to show images. My code looks like this :

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>
);
}}

I have basically tried everything that I could think of including initializing stuff in ponentDidMount. Using conditional rendering to check for length of the array and only display if anything exists. The picture Array is an array that contains the images with ids that I want to display in the carousel. I am getting it from the parent container like this:

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>
        );
    }

The data is already there when it goes to the child ponent and I have double checked it too by logging it out in the constructor. I tried putting the API in ponentDidMount and setting the state in the child ponent too but that didn't work either.

I have tested out the same data that I am fetching from the API locally and that seems to work from a JSON but when I get it from a remote server it doesn't work. The only time it shows data from the server is when i make changes to the code and it active reloads then somehow the data is visible there but not the first time.

I think the ponent doesn't re-render or something. Is there a way to do a force refresh on the child ponent to make it work? I have read answers that say when setState is called it automatically triggers a re-render but in my case nothing seems to work.

I am receiving props from a parent container and I am using a Carousel in the child ponent to show images. My code looks like this :

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>
);
}}

I have basically tried everything that I could think of including initializing stuff in ponentDidMount. Using conditional rendering to check for length of the array and only display if anything exists. The picture Array is an array that contains the images with ids that I want to display in the carousel. I am getting it from the parent container like this:

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>
        );
    }

The data is already there when it goes to the child ponent and I have double checked it too by logging it out in the constructor. I tried putting the API in ponentDidMount and setting the state in the child ponent too but that didn't work either.

I have tested out the same data that I am fetching from the API locally and that seems to work from a JSON but when I get it from a remote server it doesn't work. The only time it shows data from the server is when i make changes to the code and it active reloads then somehow the data is visible there but not the first time.

I think the ponent doesn't re-render or something. Is there a way to do a force refresh on the child ponent to make it work? I have read answers that say when setState is called it automatically triggers a re-render but in my case nothing seems to work.

Share Improve this question edited Apr 8, 2019 at 17:50 halfer 20.3k19 gold badges109 silver badges202 bronze badges asked Apr 6, 2019 at 1:05 BleachedAxeBleachedAxe 4032 gold badges6 silver badges23 bronze badges 5
  • Change this this.state.slides.map to this.props.pictureArray.map. You don't need state for this one – invisal Commented Apr 6, 2019 at 1:43
  • Tried that too, doesn't work. That's why i assigned it to state that maybe it re-renders but had no luck. – BleachedAxe Commented Apr 6, 2019 at 2:09
  • One things is that seems to be working is when i put a button on the page and that button when clicked runs forceUpdate(). Is there any way of running this method automatically like 1 second after rendering? – BleachedAxe Commented Apr 6, 2019 at 2:26
  • Can you show us how the parent's pictureArray is going to be set again? Also using native for loop is almost always inferior vs .map or .forEach, etc – Tyro Hunter Commented Apr 6, 2019 at 2:34
  • It's in the code that I have put up. I am taking the picture array and setting it to slides in the state of child ponent. I am using a for loop to push data to code array in the parent container in a promise so definitely the data is ready by the time it's pushed to the child container. – BleachedAxe Commented Apr 6, 2019 at 2:43
Add a ment  | 

2 Answers 2

Reset to default 2

The problem is the way you iterate against an asynchronous code. Since you are trying to populate codeArray inside a loop from an async api call, you can't use for loop otherwise getImage will not wait for your api call to resolve and therefore returns immediately while codeArray is still empty. So use other types of iterator such as .map that can work with async code.

This might help you, check this out: 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 })
}

I suggest to call getImage in ponent did mount:

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

finally in your render method: <ReactSlick pictureArray={this.state.codeArray} />

/* also set your ponent statecodeArrayas an empty array to be safe */

P.S: I assumed images was already set from the parent's props (but it could be in state as well). If images will have 10 items, and api() call takes 1 second to finish, therefore getImage() will take around 10 seconds then call setState or update your ponent (as well as the child ReactSlick)

I hope this helps

You have existing props, why would you use the state to iterate loop? Another solution for this one is using self-route. So whenever the API has fetched data successfully.

发布者:admin,转转请注明出处:http://www.yc00.com/questions/1742340533a4425535.html

相关推荐

发表回复

评论列表(0条)

  • 暂无评论

联系我们

400-800-8888

在线咨询: QQ交谈

邮件:admin@example.com

工作时间:周一至周五,9:30-18:30,节假日休息

关注微信