Will
Will

Reputation: 161

Where should I call a method to use data from it?

I'd like to call getAlbums() method so I can use the data from the get request and display album data on the client side. I don't know where to call it though. I tried to call it in render() but it creates an infinite loop.

Albums.js

import React, { Component } from "react";
import { useParams } from "react-router-dom";
import axios from "axios";
import AlbumCard from "./AlbumCard";

export class Albums extends Component {
  constructor(props) {
    super(props);

    this.state = { albums: [] };
    this.getAlbums = this.getAlbums.bind(this);
  }

  async getAlbums() {
    const {
      match: { params },
    } = this.props;
    console.log(params.id);
    try {
      const res = await axios.get(
        `http://localhost:4000/albums/${encodeURIComponent(params.id)}`,
        {
          params: {
            id: params.id,
          },
        }
      );
      console.log(`Returned album data from the server: ${res}`);
      this.setState({ albums: res.data });
    } catch (err) {
      console.log(err);
    }
  }

  render() {
    return (
      <>
        <div className="container" style={{ color: "white" }}>
          hello
        </div>
      </>
    );
  }
}

export default Albums;

I wanna do something like this inside the div.

this.state.albums.map((album) => (<AlbumCard img={album.img}/>))

Upvotes: 1

Views: 90

Answers (3)

Frosty619
Frosty619

Reputation: 1489

The reason you get an infinite loop is because you're calling setState in render. Here is what's happening behind the scenes:

1.getAlbums is called in the render method.

2.The function triggers setState.

3.setState causes re-render.

4.In the render method, getAlbums is called again.

Repeat 1-4 infinitely!

Here's is what you could do:

  1. Create a button and bind getAlbums as a method to the onClick event handler.

2.Run getAlbums on ComponentDidMount like so:

  componentDidMount() {
      this.getAlbums();
    }

Upvotes: 2

Gopinath
Gopinath

Reputation: 4947

componentDidMount() is the best place for making AJAX requests.

The componentDidMount() method will set state after the AJAX call fetches data. It will cause render() to be triggered when data is available.

Here is the working example with componentDidMount()

import React, { Component } from "react";
import { useParams } from "react-router-dom";
import axios from "axios";
import AlbumCard from "./AlbumCard";

export class Albums extends Component {
  constructor(props) {
    super(props)
    this.state = { albums: [] }
  }

  componentDidMount() {
      axios.get( 
                `http://localhost:4000/albums/${encodeURIComponent(this.props.id)}`,
                { params: { id: this.props.id } }
            )
           .then(response => {
                  console.log(`Returned album data from the server: ${res}`)
                  this.setState({ albums: response.data })
                }
            )
           .catch(e => {
                   console.log("Connection failure: " + e)
                }
           )
  }

  render() {
    return (
        <div>
            {/*   Code for {this.state.albums.map(item => )}  */}
            {/*   render() method will be called whenever state changes.*/}
            {/*   componentDidMount() will trigger render() when data is ready.*/}
        </div>
    )
  }
}

export default Albums

More information:

https://blog.logrocket.com/patterns-for-data-fetching-in-react-981ced7e5c56/

Upvotes: 0

Anuresh Verma
Anuresh Verma

Reputation: 1058

use componentDidMount()

componentDidMount(){
getAlbums() 
}

Upvotes: 0

Related Questions