Search code examples
reactjsfetch-apidynamic-url

How to generate dynamic url with state in componentDidMount?


I want to dynamic the URL with {this.state.whatever} in componentDidMount but failed. Because the state value is undefined(I run the console.log and the error also shows it)

I thought componentDidMount runs after the state reset, so I can use the updated state in the URL but doesn't work, I wonder why

state={ breed: "" }
async componentDidMount(){
   try {
       const res = await 
       fetch(`https://dog.ceo/api/breed/${this.state.breed}/images`);
       const data = await res.json();
       const imageUrl = data.message;
       this.setState({
         puppyImage: imageUrl
       })

   } catch (error) {
     console.log(error);
   }
 }

 onChangeHandler = event => {
   this.setState({breed: event.target.value})
 };

this URL doesn't work because of {this.state.breed} is undefined, which means it hasn't been updated. the error shows: GET https://dog.ceo/api/breed//images 404


Solution

  • componentDidMount() will only run a single time after the component renders, and never again.

    You should use componentDidUpdate() instead which is triggered anytime the component gets an updated state or props. Within it, you can configure logic to determine whether you should do a new fetch.

    componentDidUpdate(prevProps, prevState){
       if(prevState.breed !== this.state.breed){
         try {
           const res = await 
           fetch(`https://dog.ceo/api/breed/${this.state.breed}/images`);
           const data = await res.json();
           const imageUrl = data.message;
           this.setState({
             puppyImage: imageUrl
           })
    
         } catch (error) {
           console.log(error);
         }
       }
     }
    

    Under the assumption that you do something that changes this.state.breed. The componentDidUpdate() logic defined above would trigger then check if their is a difference between the previous breed state and the updated breed state. If there is, then a new fetch-call is made with that breed and you will get a new puppyImage :).