componentDidUpdate() 在数据获取时多次渲染



我有一个组件,可以在componentDidMount()中同时调用两个 GET API。第二个 API(服务(的结果基于第一个 API(注册(。

此外,我使用处理程序将一些数据提交到另一个 POST API,该处理程序最终会更新第二个 GET API 中的数据。由于我的第二个 API 是在 componentDidMount(( 中调用的,因此它只呈现一次。

然后,我使用componentDidUpdate()修复了它,以处理组件中所做的更改,并相应地在我的组件状态chatServices反映新添加的数据。

class ViewRegistrations extends Component{
constructor(props) {
super(props)
this.state = {
queryParam:'',
dataReceived: [],
isShowing: false,
registeredDataAvailable: false,
company_id: '',
chatServices: []
}
}
async componentDidMount(){
const queryParam = new URLSearchParams(this.props.location.search).get('registration');
await this.setState({
queryParam: queryParam
}, () => {
this.fetchRegistrationData(queryParam);
this.fetchChatServices(queryParam);
});
}
fetchRegistrationData = async (id) => {
axios.get(`BASE_URL+/api/company/list?id=${id}`, {headers: LocalData.headers })
.then(res => {
if(res.status === 200 && res.data.status === true){
let dataReceived = this.state.dataReceived;
let chatsReceived = res.data.data;
dataReceived = chatsReceived;
this.setState({
dataReceived,
registeredDataAvailable: res.data.status,
});
}
else{
const error = new Error('Invalid Request');
this.setState({registeredDataAvailable: false});   
throw error;
}
})
.catch(err => {
console.log(err);
});
}

fetchChatServices = async (parentId) => {
await axios.get(`BASE_URL+/api/service/list?company_id=${parentId}`, {headers: LocalData.headers})
.then(res => {
if(res.status === 200 && res.data.status === true) {
let chatServices = res.data.data;
this.setState({
chatServices,
chatDataAvailable: res.data.status,
company_id: parentId
});
}
else{
const error = new Error('Invalid Request');
this.setState({chatDataAvailable: false})
throw error;
}
})
.catch(err => console.log('error occured:',err));
}

componentDidUpdate(prevProps, prevState){
let chat_data = this.state.chatServices;
if(prevState.chatServices === chat_data){
this.fetchChatServices(this.state.queryParam)
}
}

openModalHandler = async() => {
await this.setState({
isShowing: true
}) 
console.log(this.state.isShowing)
}
closeModalHandler = async() => {
await this.setState({
isShowing: false
});
}
newChatService = (closemodal) => {
this.setState({
isShowing: closemodal,
});
}
goback = () => {
this.props.history.goBack();
}
render(){
const {dataReceived, registeredDataAvailable, chatServices, isShowing, company_id} = this.state;
return(
<div>
{registeredDataAvailable === true ? dataReceived.map((data) => {
return (
<React.Fragment key={data.id}>
<Card>
<CardHeader>
<div className="form_head">
<h4>Company Details</h4>
</div>
</CardHeader>
<CardBody>
<Row>
<Col sm="12" xs="12" lg="12">
<fieldset className="fieldset_body">
<Row>
<Col lg="6" sm="12" xs="12" md="6">
<FormGroup>
<Label>Name of Organization</Label>
<Input placeholder={data.name} readOnly/>
</FormGroup>
</Col>
<Col lg="6" sm="12" xs="12" md="6">
<FormGroup>
<Label>Name of Authority</Label>
<Input placeholder={data.authority} readOnly/>
</FormGroup>
</Col>
</Row>
<Row>
<Col lg="6" sm="12" xs="12" md="6">
<FormGroup>
<Label>Email</Label>
<Input placeholder={data.email} readOnly/>
</FormGroup>
</Col>
<Col lg="6" sm="12" xs="12" md="6">
<FormGroup>
<Label>Contact Number</Label>
<Input placeholder={data.contact} readOnly/>
</FormGroup>
</Col>
</Row>
</fieldset>
</Col>
</Row>
</CardBody>
</Card>       
<Card>
<CardHeader>
<Row>
<Col lg="6" md="6" sm="12" xs="12">
<h4>Chat Services</h4>
</Col>
<Col lg="6" md="6" sm="12" xs="12">
<Button className="pull-right" onClick={this.openModalHandler}>Add Chat Services</Button>
</Col>
</Row>
</CardHeader>
<CardBody>
{
chatServices.length ? (
<ChatServicesLists chatServices={chatServices} company_id={company_id} />  
)
: 
(
<Row>
<Col xs="12" sm="12" md="12" lg="12">
<p className="text-center">Chat Services Not Available !</p>
</Col>
</Row>
)
}
</CardBody>
........
}

我的问题是,我的组件现在被渲染了 3-4 次;一旦组件挂载并添加新数据。在这两种情况下,它都会渲染大约 3-4 次。

请帮助了解相关的问题,并避免这种不必要的组件渲染。

componentDidUpdate(prevProps, prevState){
let chat_data = this.state.chatServices;
if(prevState.chatServices.length !== chat_data.length){
this.setState({chatServices:chat_data})
}
}

像这样进行更改,它将检查聊天服务的新旧数组长度

代码中有太多的 setState 语句。

当我从 api 调用获取所有数据时,我只会尝试使用 setState 一次。

一个例子是这样的:

state = {
user: null,
posts: []
};
async componentDidMount() {
const userId = this.props.userId;
const userResponse = await axios.get(
`https://jsonplaceholder.typicode.com/users/${userId}`
);
const postsResponse = await axios.get(
`https://jsonplaceholder.typicode.com/posts?userId=${userId}`
);
this.setState({
user: userResponse.data,
posts: postsResponse.data
});
}

这将只导致 2 个渲染。

代码沙盒

另外,在setState回调函数中调用api似乎不是一个好主意。

await this.setState({
queryParam: queryParam
}, () => {
this.fetchRegistrationData(queryParam);
this.fetchChatServices(queryParam);
});

最新更新