admin管理员组文章数量:1332700
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.
本文标签: javascriptReact component doesn39t rerender after state changeStack Overflow
版权声明:本文标题:javascript - React component doesn't re-render after state change - Stack Overflow 内容由网友自发贡献,该文观点仅代表作者本人, 转载请联系作者并注明出处:http://www.betaflare.com/web/1742340533a2456511.html, 本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。
发表评论