Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

setState not working in componentDidMount() - React

I have been having a few problems with using the setState function in componentDidMount().

What I am trying to do: I am trying to make an HTML5 circle responsive (Go bigger if browser window is bigger and vice versa).

What I have done so far: I have been storing the dimensions in state called containerDim. By Default this is set to null. Here is a very basic implementation of what I've done:

class App extends React.Component  {
  constructor(props)  {
    super(props);
    this.state = {containerDim: null};
    this.resizeCircle = this.resizeCircle.bind(this)  //To not loose value of this
  }

  componentDidMount()  {

    var dimensions = window.getComputedStyle(this.refs.responsiveContainer); //Used to get width and height

    this.setState({
      containerDim: {width:dimensions.width, height: dimensions.height}
    });

   window.addEventListener("resize", this.resizeCircle));

  }

 resizeCircle()  {  //THE RESIZING WORKS, THE initial setting of state doesn't
   var dimensions = window.getComputedStyle(this.refs.responsiveContainer); //Used to get width and height

    this.setState({
      containerDim: {width:dimensions.width, height: dimensions.height}
    });

 }



  render()  {
    return (
     <div ref={"responsiveContainer"} >
       <Circle dimensions={this.state.containerDim} />
     </div>
    );
  }
} 

//Circle component

class Circle extends React.Component {
  constructor(props)  {
    super(props);
  }

  componentWillReceiveProps()  {

    console.log(this.props.dimensions); //THIS LOGS OUT NULL

  }

  render()  {
    CIRCLE GOES HERE
  }

}

Basically what I am trying to do with this code is to get the width and height of "responseContainer" and pass it as a prop to the <Circle /> component.

The above does not work as the setState does not change the state whatsoever.

Any help would be greatly appreciated!

EDIT:

This "Works" but I feel that it is not correct and there should be a better way:

 var dimensions = window.getComputedStyle(this.refs.container);

  setTimeout(function()  {


  this.setState({
    screenDim:{width:dimensions.width, height:dimensions.height}
  });
}.bind(this),0);

this.setState({
  screenDim:{width:dimensions.width, height:dimensions.height}
});
like image 983
mre12345 Avatar asked Feb 04 '16 08:02

mre12345


People also ask

Can we use setState in componentDidMount?

You can call setState() immediately in componentDidMount() and triggers an extra rendering, but this happens before the browser updates the screen, calling render() twice.

How do I use componentDidMount in React?

The example below shows a classical approach to access componentDidMount(). import React, { Component } from 'react'; class App extends Component { componentDidMount() { // Runs after the first render() lifecycle console. log("Did mount called"); } render() { console.

What can I use instead of componentDidMount?

The equivalent of the componentDidUpdate lifecycle method is also the useEffect hook. componentDidUpdate runs when a state or prop changes values. We can do the same thing with useEffect by passing in the state or prop values we want to watch into the array we pass into the 2nd argument of useEffect .

Is componentDidMount equal to useEffect?

Here's Why. It's very common to require some setup when a component is mounted to perform tasks like network calls. Before hooks were introduced we were taught to use functions like componentDidMount() .


1 Answers

The component does not listen to state modifications in didMount; that means that even if the state is updated the repaint is not triggered.

like image 59
pinturic Avatar answered Sep 22 '22 14:09

pinturic