0

I have a working Django REST API which returns this:

{
    "id": 1,
    "brand": "peugeot",
    "model": "3008",
    "variant": "allure"
}

I am using the following code to fetch the above data:

render() {
        const { brand, model, variant } = this.props;
        let url = `http://127.0.0.1:8000/api/car/${brand}/${model}/${variant}/`;
        console.log(url) <== url is correct when checked in console
        fetch(url)
            .then(response => response.json())
            .then(data => data.length === 0 ? this.setState({
                data : data
            }) : null ) <== I have used a condition for setState to stop fetching infintely

        const { data } = this.state;
        console.log(data) <== This is a blank object with no data in console
        console.log(data.id) <== This is undefined in console
        return (
            <div>
                {data.id} <== No data is shown on webpage
                Car Details
            </div>
        );
    }

No error is shown when I try to fetch the data on my webpage. What am I doing wrong?

P.S. Data can be fetched from the same API server when I have an array of objects, and I use map to loop over the data. Over here I am trying to fetch a single item so there is no array, just an object. Am I doing something wrong with the syntax?

3 Answers 3

3

You should never fetch or setState inside the render function.

render is called many times due to all kinds of side effects, i.e scrolling, clicking, props changing etc. This kind of code could cause all kinds of trouble.

If you need to perform the request once, call the fetch function inside componentDidMount. Also, I believe your callbacks should look something like this:

fetch(url)
  .then(response => response.json())
  .then(data => this.setState({ data : data }))

Taken from the docs:

componentDidMount() is invoked immediately after a component is mounted. Initialization that requires DOM nodes should go here. If you need to load data from a remote endpoint, this is a good place to instantiate the network request.

Sign up to request clarification or add additional context in comments.

1 Comment

I followed your advice and fetched data in componentDidMount and componentDidUpdate. Thanks.
1

I changed the condition before 'setState' to JSON.stringify(data) !== JSON.stringify(this.state.data) and now it works.

1 Comment

This is very bad practice. I suggest reading my answer to understand better why.
0

should it be:

.then(data => data.length > 0 ? this.setState({ data }) : null )

2 Comments

However, if I remove the condition altogether, it infinitely calls the API but displays the data correctly.
While this code snippet may be the solution, including an explanation really helps to improve the quality of your post. Remember that you are answering the question for readers in the future, and those people might not know the reasons for your code suggestion.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.