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
tothis.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 usingnative 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
2 Answers
Reset to default 2The 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 state
codeArrayas 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条)