My problem is in my subcomponent files where every state update in the parent component keeps re-rendering the subcomponents infinitely by making infinite api calls with the default or updated props value passed to the child components. I have a User directory page which contains multiple components in a single page.
class Users extends Component {
constructor(props) {
super(props);
this.state = {
user: "",
listOfUsers: [],
socialData:[],
contactData:[],
videoData:[],
detailsData:[]
}
}
componentDidMount(){
//api call that gets list of users here
//set response data to this.state.listOfUsers
}
userHandler = async (event) => {
this.setState({
user: event.target.value,
});
};
render() {
return (
<div>
<div>
<select
value={this.state.user}
onChange={this.userHandler}
>
// list of users returned from api
</select>
</div>
<div>
<Social Media user={this.state.user} />
<Contact user={this.state.user}/>
<Video user={this.state.user}/>
<Details user={this.state.user}/>
</div>
</div>
);
}
}
I have 1 API call for the parent component Users, and 4 for each of the subcomponents: Social Media, Contact, Video, and Details. The Users api will return a list of users in a dropdown and the value of the user selected is then fed to the other four API's. i.e. https://localhost:3000/social_media?user=${this.state.user}. Thus, the four subcomponents' API is dependent on the Users API. I currently have the parent api call in a componentDidMount() and the other 4 api calls in their respective subcomponents and use props to pass down the value of the user selected in the parent to the subcomponents. Each of the api calls is in a componentDidUpdate(prevProps). All the subcomponents follow this structure:
class Social Media extends Component {
constructor(props) {
super(props);
this.state = {
user: "",
socialData:[],
}
}
componentWillReceiveProps(props) {
this.setState({ user: this.props.user })
}
componentDidUpdate(prevProps){
if (this.props.user !== prevProps.user) {
// make api call here
fetch (`https://localhost:3000/social_media?user=${this.state.user}`)
.then((response) => response.json())
.catch((error) => console.error("Error: ", error))
.then((data) => {
this.setState({ socialData: Array.from(data) });
}
}
render() {
return (
{this.socialData.length > 0 ? (
<div>
<Social Media data={this.state.socialData}/>
</div>
)
:
(<div> Loading ... </div>)
);
}
}