Search code examples
javascriptreactjsreact-class-based-component

Why my state is not getting set inside class based component and it should work but it is not neither i am getting error


The issue i am facing is i am not able to set my state in the class based component i don't know whats wrong with it i have created a very small project before this so that i can practice the state manipulation and i am doing the same way as test project working please help

import React, { Component } from 'react';
import { Header } from './components';
import { ProductListing, ProductDetail, Cart } from './Screens';

import {
    Routes,
    Route,
    Navigate
} from "react-router-dom";

export class App extends Component {
    constructor(){
        super();
        this.state = {
            products: [],
            cart: []
        }
    }

    async componentDidMount() {
        const query = `
    query{
      categories {
          name
          products {
            id,
            name,
            inStock,
            gallery,
            category
          }
        }
  }
    `;
        fetch("http://localhost:4000", {
            method: "POST",
            headers: {
                "Content-Type": "application/json",
                "Accept": "application/json",
            },
            body: JSON.stringify({
                query
            })
        }).then(response => {
            return response.json();
        }).then(data => {
            this.setState({
                products: data.data.categories,
            })
            console.log("The data i am getting is", data.data.categories);
            
        })
        console.log("The prodcuts are", this.state.products)
    }
    render() {
        return (
            <>
                <Header />
                <Routes>
                    <Route path="/" element={<Navigate replace to="/all" />} />
                    <Route path="/:category" element={<ProductListing products={this.state.products} />} />
                    <Route path="/product" element={<ProductDetail />} />
                    <Route path="/cart" element={<Cart />} />
                </Routes>
            </>
        )
    }
}

export default App

I don't understand why this piece of code is not working it is supposed to set the data and send it to the component but is not doing that actually and neither giving error

this.setState({
             products: data.data.categories,
         })

the below piece of code

console.log("The data i am getting is", data.data.categories);

enter image description here


Solution

  • this.setState is an asynchronous function
    and console.log("The prodcuts are", this.state.products) is a synchronous code
    so it doesn't print the correct result
    You can print the data in the callback function of this.setState
    like this

    this.setState({...}, () => {
      console.log(...)
    })
    

    You should be able to get the correct result
    And in the ProductListing component
    I'm not sure when you're printing the console.log
    because your data is being requested asynchronously and you're getting
    and the rendering of the child component is not necessarily done after the request
    So if you want to successfully print the data from the child component
    either during the update lifecycle
    or in the render function
    Hope this helps you out