ReactJS中componentDidUpdate()之后的无限循环

问题描述 投票:0回答:3

我有React JS应用,该应用使用ASP .NET Core Web API中的条目更新boostrap网格表。

并且我需要在插入后用新条目更新网格。我是在componentDidUpdate()的帮助下并在那里使用refreshList()函数的,但是我正在获得refreshList()函数的无限循环。

enter image description here

关于如何在没有循环的情况下更新网格的任何想法?

import React, {Component} from 'react';
import {Table, Container} from 'react-bootstrap';
import {Button, ButtonToolbar} from 'react-bootstrap';

import {AddDepModal} from './AddDepModal';
import {EditDepModal} from './EditDepModal';

export class Department extends Component {

    constructor(props){
        super(props);
        this.state = {deps:[], addModalShow: false, editModalShow: false}
    }

    componentDidMount()
    {
        this.refreshList();
    }
    refreshList()
    {
       fetch("https://localhost:5001/api/departments")
       .then(response=> response.json())
       .then(data=> { 
        this.setState({deps:data});
       });
    }

    componentDidUpdate()
    {
        this.refreshList();
    }

    render(){

     const {deps, depid, depname} = this.state;
     let addModalClose = () => this.setState({addModalShow:false})
     let editModalClose = () => this.setState({editModalShow:false})
    return (
        <div>
     <Table className = "mt-4" striped bordered hover size ="sm">
    <thead>
        <tr>
            <th>DepartmentID</th>
            <th>DepartmentName</th>
            <th>Options</th>
        </tr>
    </thead>
    <tbody>
        {deps.map(dep=> 
            <tr key = {dep.id}> 
            <td>{dep.id}</td>
            <td>{dep.name}</td>
            <td>
                <ButtonToolbar>
                    <Button
                    className ="mr-2" variant ="info"
                    onClick = {() => this.setState({editModalShow:true, depid: dep.id, depname: dep.name})}
                    >
                        Edit
                    </Button>
                    <EditDepModal
                    show = {this.state.editModalShow}
                    onHide = {editModalClose}
                    depid = {depid}
                    depname = {depname}/>
                </ButtonToolbar>
            </td>
            </tr>
            )}
    </tbody>
     </Table>
     <ButtonToolbar>
    <Button variant = "primary" onClick = {() => this.setState({addModalShow: true})}>Add Department</Button>
    <AddDepModal 
    show ={this.state.addModalShow} 
    onHide ={addModalClose}/>
</ButtonToolbar>
</div>
    )
    }
}
javascript reactjs
3个回答
1
投票

问题是您正在componentDidMount和componentDidUpdate中调用refreshList。如文档中所述:https://reactjs.org/docs/react-component.html#componentdidupdate

您应该在某种情况下避免componentDidUpdate中的无限循环。


1
投票

删除componentDidUpdate(),因为refreshData不依赖于道具来获取数据,并且不对prevProps和newProps进行任何检查。

您可以从添加或保存按钮回调中调用refreshData方法。

我认为您正在从模式代码中保存数据,请添加setState回调。

模式保存数据,隐藏设置显示状态为false并一次调用refreshData。

let addModalClose =()=> this.setState({addModalShow:false},this.refreshData)


0
投票

您正在调用this.refreshList();,它会执行某些操作,然后设置状态。设置状态后,将调用render函数,然后再次调用componentDidUpdate,从而设置无限循环。要使其工作,请与先前的props比较,然后根据需要调用this.refreshList();

componentDidUpdate(prevProps) {
  // Typical usage (don't forget to compare props):
  if (this.props.depid !== prevProps.depid) { //Replace `depid` with the props you like to compare changes. If that is changed, then only call
    this.refreshList();
  }
}

您可以立即在componentDidUpdate()中调用setState(),但请注意必须将其包装在上面示例中所示的条件下,或者您将导致无限循环。这也会造成额外的重新渲染虽然对用户不可见,但可能会影响组件性能。如果您尝试将某些状态“镜像”到道具来自上方,请考虑直接使用道具。读有关为何将道具复制到状态会导致错误的更多信息。

请参阅文档:https://reactjs.org/docs/react-component.html#componentdidupdate

© www.soinside.com 2019 - 2024. All rights reserved.