Reputation: 1583
I am trying to make my component reactive on updates. I am using componentDidUpdate()
to check if the components prop state has changed, then if it has it is has I need the getPosts()
function to be called and the postCount
to update if that prop is changed.
export default class JsonFeed extends React.Component<IJsonFeedProps, IJsonFeedState> {
// Props & state needed for the component
constructor(props) {
super(props);
this.state = {
description: this.props.description,
posts: [],
isLoading: true,
jsonUrl: this.props.jsonUrl,
postCount: this.props.postCount,
errors: null,
error: null
};
}
// This function runs when a prop choice has been updated
componentDidUpdate() {
// Typical usage (don't forget to compare props):
if (this.state !== this.state) {
this.getPosts();
// something else ????
}
}
// This function runs when component is first renderd
public componentDidMount() {
this.getPosts();
}
// Grabs the posts from the json url
public getPosts() {
axios
.get("https://cors-anywhere.herokuapp.com/" + this.props.jsonUrl)
.then(response =>
response.data.map(post => ({
id: `${post.Id}`,
name: `${post.Name}`,
summary: `${post.Summary}`,
url: `${post.AbsoluteUrl}`
}))
)
.then(posts => {
this.setState({
posts,
isLoading: false
});
})
// We can still use the `.catch()` method since axios is promise-based
.catch(error => this.setState({ error, isLoading: false }));
}
Upvotes: 3
Views: 186
Reputation: 2786
Try doing this
componentDidUpdate(prevState){
if(prevState.loading!==this.state.loading){
//do Something
this.getPosts();
}}
Upvotes: 0
Reputation: 664
// This function runs when a prop choice has been updated
componentDidUpdate(prevProps,prevState) {
// Typical usage (don't forget to compare props):
if (prevState.jsonUrl !== this.state.jsonUrl) {
this.getPosts();
// something else ????
}
}
this way you have to match with the updated state
Upvotes: 1
Reputation: 962
You can change componentDidUpdate to:
componentDidUpdate() {
if (this.state.loading) {
this.getPosts();
}
}
This won't be an infinite loop as the getPosts() function sets state loading to false;
Now every time you need an update you just need to set your state loading to true.
If what you want to do is load everytime the jsonUrl updates then you need something like:
componentDidUpdate(prevProps) {
if (prevProps.jsonUrl!== this.props.jsonUrl) {
this.getPosts();
}
}
Also I don't get why you expose your components state by making componentDidMount public.
Upvotes: 4
Reputation: 39250
Modify your getPosts to receive the jsonUrl argument and add the following function to your class:
static getDerivedStateFromProps(props, state) {
if(props.jsonUrl!==state.jsonUrl){
//pass jsonUrl to getPosts
this.getPosts(props.jsonUrl);
return {
...state,
jsonUrl:props.jsonUrl
}
}
return null;
}
You can get rid of the componentDidUpdate function.
You can also remove the getPosts from didmount if you don't set state jsonUrl in the constructor.
Upvotes: 2