Home > Software engineering >  SetState in Class Component is not running (ReactJS)
SetState in Class Component is not running (ReactJS)

Time:01-05

I want to pass an ID of a specific gallery-image to it's details page which is a child-component of gallery.

To achieve this I call an onClick-Function, handleClick, when the image is selected. (So that the key is passed as new prop to the child-component)

The onClick-function is but the setState within will not be executed.

The state doesn't change and the key (this.state.key) is not passed as a new value (nextprop) to the child-component.

Here is my code:

import io from 'socket.io-client';
import React, { Component } from "react";
import { GridList, GridListTile } from "@material-ui/core";
import ImageList from '@material-ui/core/ImageList'
import { Container } from 'react-bootstrap';
import { ImageListItem } from '@material-ui/core'
import { ImageListItemBar } from '@material-ui/core';
import ListSubheader from '@material-ui/core';
import IconButton from '@material-ui/core';
import InfoIcon from '@material-ui/core';
import styles from '../styles/ImageGallery.module.scss';
import Delete from '@mui/icons-material/Delete';
import FavoriteBorder from '@mui/icons-material/FavoriteBorder';
import { BrowserRouter as Router, Route, Switch, Link} from "react-router-dom";
import ItemDetail from "../pages/Items";

export default class IGallery extends React.Component {
    constructor(props) {
      super(props);    
/*       this.countryList = {
        key: 'test',
        name:'test'
      } */
      //this.handleClick = this.handleClick.bind(this);

      this.state = {
         countryList: [],
         wallet:'',
         key:''    }
     
      this.socket = io('http://localhost:3000')
      this.socket.on('new_data', (value) => this.handleMessage(value));
   
      this.socket.on('disconnect', function(){
      this.socket.disconnect();
    });
     
    }

    handleMessage(value) {

   
       let imageDataSet=(JSON.parse(value).new_val);
       console.log("New Data " value['new_val']);
       //let imageDataSet = value2.new_val;
       console.log("Test " imageDataSet);
       //console.log("Test " imageDataSet.id);
      this.setState({
          countryList: [ ...this.state.countryList, {key:imageDataSet.id, image:imageDataSet.image}, ],
      }) 
    
    }


    handleClick = (_key) => {
        console.log("Key of Gallery Image " _key);
        console.log('before setState', this.state.key)
        this.setState({key:_key}, console.log('after setState', this.state.key));
  
      
    }


    render()
    {

    return (

        <div className={styles.gallery}><h1>Gallery</h1>
         
    
    <ImageList cols={6} rowHeight={320}>
        {this.state.countryList.map((data, idx) => (
         <ImageListItem  key={idx} className={styles.imageItem}>
           <Link to="/item" onClick={() => this.handleClick(data.key)}>
            <img src={data.image}  width={320} /><ItemDetail key={this.state.key}></ItemDetail> 
           </Link>
          </ImageListItem >
        ))}
      </ImageList >
     
        </div>
      );
    }
    
  }

I expect that the console-log displays the new state.

   this.setState({key:_key}, console.log('after setState', this.state.key));

CodePudding user response:

From setState() documentation

The second parameter to setState() is an optional callback function that will be executed once setState is completed and the component is re-rendered.

So you must pass a callback (instead of calling directly console.log)

this.setState({key:_key}, () => console.log('after setState', this.state.key));

CodePudding user response:

setState works asynchronously, You cannot get its value soon after it is set, it would take some time.

To know if the state is set use the useEffect with the state dependency.

useEffect(()
  {console.log(this.state.key)} 
   // If you want to navigate to Details page once key is set 
   .....            
  • Related