Reactjs 反应:更新数组中的组件
我有一个React组件,它包含一系列子组件。父级从服务检索数据并将其存储在状态。它通过道具将数据数组中的一项传递给每个子组件 子组件包括更新其数据项中的值的功能。当它执行此操作时,会触发一个事件,将更新的项传递回父项。父级创建一个新的状态数组,包括更新的项 下面是简化的代码 这一切都很好,更新数组在父级的渲染方法中处理。但是,子组件永远不会重新渲染,因此更新的属性将保持其以前的值 如何使相关子组件显示更新的状态Reactjs 反应:更新数组中的组件,reactjs,Reactjs,我有一个React组件,它包含一系列子组件。父级从服务检索数据并将其存储在状态。它通过道具将数据数组中的一项传递给每个子组件 子组件包括更新其数据项中的值的功能。当它执行此操作时,会触发一个事件,将更新的项传递回父项。父级创建一个新的状态数组,包括更新的项 下面是简化的代码 这一切都很好,更新数组在父级的渲染方法中处理。但是,子组件永远不会重新渲染,因此更新的属性将保持其以前的值 如何使相关子组件显示更新的状态 class SearchView extends Component { p
class SearchView extends Component {
pageSize = 20;
constructor(props) {
super(props);
this.state = {
searchTerm: this.props.searchTerm,
results: []
};
}
getResults = (page) => {
const from = (page - 1) * this.pageSize;
searchActions.termSearch(this.state.searchTerm, from, this.pageSize).then(response => {
const results = response.SearchResultViews;
this.setState({
results: results
});
});
}
componentDidMount() {
this.getResults(1);
}
refresh(result){
const results = this.state.results.map(r => {
return (r.Id === result.Id) ? result : r;
});
this.setState({
results: results
});
}
render() {
let items = [];
if (this.state.results.length > 0) {
items = this.state.results.map((result, i) => {
return <SearchItem key={i} result={result} onStatusUpdate={(r) => this.refresh(r)}></SearchItem>;
});
}
return (
<div className="r-search-result">
<Row className='clearfix scroller'>
<div className='r-container-row results'>
{ items }
</div>
</Row>
</div>
);
}
}
class SearchItem extends Component {
constructor(props) {
super(props);
}
updateStatus(newValue) {
resourceActions.updateStatus(newValue);
//Bubble an event to the Parent to refresh the result and view
if (props.onStatusUpdate) {
searchActions.get(props.result.Id).then((result) => {
props.onStatusUpdate(result);
});
}
}
render() {
return (
<a href={this.props.result.link}>
<span className="column icon-column">{this.props.result.imageUrl}</span>
<span className="column title-column">{this.props.result.titleLink}</span>
<span className="column status-column">{this.props.result.status}</span>
<span className="column button-column"><button onClick={() => this.UpdateStatus(5)}></button></span>
</a>
);
}
}
类SearchView扩展组件{
页面大小=20;
建造师(道具){
超级(道具);
this.state={
searchTerm:this.props.searchTerm,
结果:[]
};
}
getResults=(第页)=>{
const from=(第1页)*this.pageSize;
searchActions.termSearch(this.state.searchTerm,from,this.pageSize)。然后(response=>{
const results=response.searchresultview;
这个.setState({
结果:结果
});
});
}
componentDidMount(){
这是结果(1);
}
刷新(结果){
constresults=this.state.results.map(r=>{
返回(r.Id==result.Id)?结果:r;
});
这是我的国家({
结果:结果
});
}
render(){
设项目=[];
如果(this.state.results.length>0){
items=this.state.results.map((result,i)=>{
返回这个。刷新(r)}>;
});
}
返回(
{items}
);
}
}
类SearchItem扩展组件{
建造师(道具){
超级(道具);
}
更新状态(新值){
resourceActions.updateStatus(newValue);
//将事件冒泡到父级以刷新结果和视图
如果(道具状态更新){
searchActions.get(props.result.Id)。然后((result)=>{
道具状态更新(结果);
});
}
}
render(){
报税表(
);
}
}
编辑
在我的实际(非简化)应用程序中,子组件转换在ComponentDidMount()
方法中传递的道具,并在状态中设置值;render方法将标记绑定到state,而不是props。按照@Vishal在注释中的建议,在子级的Render()
方法中放置断点后,我可以看到子级收到了更新的数据,但由于状态尚未更新,因此组件不会显示更新的数据
接下来的问题是,如何在不导致无限渲染循环的情况下最好地更新组件状态 最后,我通过在
componentWillUpdate()
中将子组件的属性转换为状态,以及componentDidMount()
方法,解决了这个问题。如以下代码所示:
componentDidMount() {
if (this.props.result) {
this.prepareRender();
}
}
componentWillUpdate(nextProps, nextState) {
if (nextProps.result.status!== this.props.result.status) {
this.prepareRender();
}
}
prepareRender() {
//simplified
this.setState({
imageUrl: this.props.result.imageUrl,
titleLink: this.props.result.titleLink,
status: this.props.result.status
});
}
render() {
return (
<a href={this.props.result.link}>
<span className="column icon-column">{this.state.imageUrl}</span>
<span className="column title-column">{this.state.titleLink}</span>
<span className="column status-column">{this.state.status}</span>
<span className="column button-column"><button onClick={() => this.UpdateStatus(5)}></button></span>
</a>
);
}
componentDidMount(){
如果(此.props.result){
这个.prepareRender();
}
}
组件将更新(下一步,下一步状态){
if(nextrops.result.status!==this.props.result.status){
这个.prepareRender();
}
}
制备程序(){
//简化
这是我的国家({
imageUrl:this.props.result.imageUrl,
titleLink:this.props.result.titleLink,
状态:this.props.result.status
});
}
render(){
报税表(
);
}
更新
在React 16.3中,不推荐使用
componentWillUpdate()
方法。此解决方案应使用新的getDerivedStateFromProps()
生命周期方法,如下所述:。您确定在SearchItem中承诺随后得到执行(并调用props.onStatusUpdate)?是的,所有工作都按计划进行。如果在refresh/render方法期间在子组件构造函数中放置断点,它将永远不会被调用,子组件的构造函数将只被调用一次。只需在child.ok的render方法上设置一个断点!这就解释了一些事情!