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}
});
You can call setState() immediately in componentDidMount() and triggers an extra rendering, but this happens before the browser updates the screen, calling render() twice.
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.
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 .
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() .
The component does not listen to state modifications in didMount; that means that even if the state is updated the repaint is not triggered.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With