Reputation: 702
I'm passing information from Component A from the Component B. After that depending on the props id I'm calling an API and setting the data to states. However, when I called the setState parameter to set the the API loaded data, the API were been called contentiously. Here's the Component B code:
import React, { Component } from 'react';
import { connect } from 'react-redux';
import Modal from "react-bootstrap/Modal";
import PropTypes from 'prop-types'
import axios from 'axios';
import TextBox from '../../layouts/textBox'
import { getPermission } from '../../actions/permissionActions';
class Form extends Component {
state = {
editSelectedPermissions: []
}
async componentDidMount() {
this.props.getPermission();
}
async componentDidUpdate() {
const roleId = this.getRoleId();
if (roleId) {
const res = await axios.get(`http://localhost:3000/v1/permissions/role/${roleId}/`);
console.log(res.data.data);
if ( res.data.data.permission.length != 0) {
this.setState({
editSelectedPermissions: res.data.data.permission
})
}
}
}
getRoleId=()=> this.props.data.id
render() {
const { onCloseModal, onSubmit, onChange, onCheckBox, permissions } = this.props;
const { showModal, id, name, description} = this.props.data;
const { editSelectedPermissions } = this.state;
let selectedPermission = false;
return (
<div>
<Modal show={showModal} centered onHide={onCloseModal}>
<Modal.Header closeButton>{id ? "Edit" : "Add"} User Role</Modal.Header>
<Modal.Body>
<form onSubmit={onSubmit.bind(this)}>
<input type="hidden" name="id" value={id} />
<div className="form-row">
<div className="col-md-6">
<TextBox type="text" name="name" placeholder="Enter Name" label="Name" value={name} onChange={onChange} />
</div>
<div className="col-md-6">
<TextBox type="text" name="description" placeholder="Enter Description" label="Description" value={description} onChange={onChange} />
</div>
</div>
{permissions.map((item, index) => {
if (editSelectedPermissions.length > 0)
selectedPermission = editSelectedPermissions.find((item2) => item2.id === item.id)
return (
<div className="form-check" key={index}>
<input className="form-check-input" type="checkbox" name="permission" checked={selectedPermission} onChange={onCheckBox} value={item.id}/>
<label className="form-check-label" htmlFor="defaultCheck1">
{item.name}
</label>
</div>
)
})}
<div className="d-flex justify-content-center">
<input
type="submit"
className="btn btn-primary"
value={id ? "Edit Record" : "Create Record"}
/>
</div>
</form>
</Modal.Body>
</Modal>
</div>
);
}
}
Form.propTypes = {
getPermission: PropTypes.func.isRequired,
}
const mapStateToProps = (state) => ({
permissions: state.permission.permissions
});
export default connect(mapStateToProps, {getPermission} )(Form);
Any reason why it's been called continuously?
Upvotes: 0
Views: 61
Reputation: 2877
componentDidUpdate
run each time state or props change. Because you setState
inside, after it it will run again, change state again, and run again infinitely. Add checker before setState
if ( res.data.data.permission.length != 0 && this.state.editSelectedPermisssions != res.data.data.premission) {
this.setState({
editSelectedPermissions: res.data.data.permission
})
}
Upvotes: 1
Reputation: 1684
It is simply because your component update frequently as such it keeps making the API call and this is because you are making the API call in componentDidUpdate. Usually, you make the API call in componentDidMount
, this will make the API call once.
async componentDidMount() {
this.props.getPermission();
const res = await axios.get(`http://localhost:3000/v1/permissions/role/${roleId}/`); // should be make here
}
Not in
componentDidUpdate(){
//Avoid Making API calls here
}
Upvotes: 0
Reputation: 51
It's because
if (roleId) //always true
this statement is always true.
Maybe you could store current roleId and and do the comparision
if (this.state.currentRoleId !== roleId) {
const res = await axios.get(`http://localhost:3000/v1/permissions/role/${roleId}/`);
console.log(res.data.data);
if ( res.data.data.permission.length != 0) {
this.setState({
currentRoleId: roleId,
editSelectedPermissions: res.data.data.permission
})
}
}
Upvotes: 0
Reputation: 25
Call API in componentDidMount cycle rather than in componentDidUpdate.
Upvotes: 0