React 组件在状态更改后不会重新呈现
React component doesn't re-render after state change
我正在从父容器接收道具,我在子组件中使用旋转木马来显示图像。我的代码如下所示:
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 时它会自动触发重新渲染,但在我的情况下似乎没有任何效果。
问题在于您对 asynchronous
代码进行迭代的方式。由于您正尝试在 async api 调用 的循环内填充 codeArray,因此您不能使用 for loop
否则 getImage
将不会等待您的 api 呼叫解决,因此 returns 立即而 codeArray
仍然是空的。所以使用其他类型的迭代器,例如可以与 async code
.
一起使用的 .map
这可能对你有帮助,看看这个:
/* 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
codeArrayas an empty array to be safe */
P.S:我假设 images
已经从 parent 的道具中设置(但它也可能处于状态)。如果 images
将有 10 个项目,并且 api()
调用需要 1 秒才能完成,因此 getImage()
将花费大约 10 seconds
然后调用 setState 或更新您的组件(以及child ReactSlick
)
希望对您有所帮助
您已有 props
,为什么要使用 state
来迭代循环?另一种解决方案是使用 self-route
。因此,每当 API 成功获取数据时。
我正在从父容器接收道具,我在子组件中使用旋转木马来显示图像。我的代码如下所示:
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 时它会自动触发重新渲染,但在我的情况下似乎没有任何效果。
问题在于您对 asynchronous
代码进行迭代的方式。由于您正尝试在 async api 调用 的循环内填充 codeArray,因此您不能使用 for loop
否则 getImage
将不会等待您的 api 呼叫解决,因此 returns 立即而 codeArray
仍然是空的。所以使用其他类型的迭代器,例如可以与 async code
.
.map
这可能对你有帮助,看看这个:
/* 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
codeArrayas an empty array to be safe */
P.S:我假设 images
已经从 parent 的道具中设置(但它也可能处于状态)。如果 images
将有 10 个项目,并且 api()
调用需要 1 秒才能完成,因此 getImage()
将花费大约 10 seconds
然后调用 setState 或更新您的组件(以及child ReactSlick
)
希望对您有所帮助
您已有 props
,为什么要使用 state
来迭代循环?另一种解决方案是使用 self-route
。因此,每当 API 成功获取数据时。