score:135
You can use setState
inside componentDidUpdate
. The problem is that somehow you are creating an infinite loop because there's no break condition.
Based on the fact that you need values that are provided by the browser once the component is rendered, I think your approach about using componentDidUpdate
is correct, it just needs better handling of the condition that triggers the setState
.
score:-2
You can use setState inside componentDidUpdate
score:-1
I had a similar problem where i have to center the toolTip. React setState in componentDidUpdate did put me in infinite loop, i tried condition it worked. But i found using in ref callback gave me simpler and clean solution, if you use inline function for ref callback you will face the null problem for every component update. So use function reference in ref callback and set the state there, which will initiate the re-render
score:0
this.setState creates an infinite loop when used in ComponentDidUpdate when there is no break condition in the loop. You can use redux to set a variable true in the if statement and then in the condition set the variable false then it will work.
Something like this.
if(this.props.route.params.resetFields){
this.props.route.params.resetFields = false;
this.setState({broadcastMembersCount: 0,isLinkAttached: false,attachedAffiliatedLink:false,affilatedText: 'add your affiliate link'});
this.resetSelectedContactAndGroups();
this.hideNext = false;
this.initialValue_1 = 140;
this.initialValue_2 = 140;
this.height = 20
}
score:2
I would say that you need to check if the state already has the same value you are trying to set. If it's the same, there is no point to set state again for the same value.
Make sure to set your state like this:
let top = newValue /*true or false*/
if(top !== this.state.top){
this.setState({top});
}
score:7
This example will help you to understand the React Life Cycle Hooks.
You can setState
in getDerivedStateFromProps
method i.e. static
and trigger the method after props change in componentDidUpdate
.
In componentDidUpdate
you will get 3rd param which returns from getSnapshotBeforeUpdate
.
You can check this codesandbox link
// Child component
class Child extends React.Component {
// First thing called when component loaded
constructor(props) {
console.log("constructor");
super(props);
this.state = {
value: this.props.value,
color: "green"
};
}
// static method
// dont have access of 'this'
// return object will update the state
static getDerivedStateFromProps(props, state) {
console.log("getDerivedStateFromProps");
return {
value: props.value,
color: props.value % 2 === 0 ? "green" : "red"
};
}
// skip render if return false
shouldComponentUpdate(nextProps, nextState) {
console.log("shouldComponentUpdate");
// return nextState.color !== this.state.color;
return true;
}
// In between before real DOM updates (pre-commit)
// has access of 'this'
// return object will be captured in componentDidUpdate
getSnapshotBeforeUpdate(prevProps, prevState) {
console.log("getSnapshotBeforeUpdate");
return { oldValue: prevState.value };
}
// Calls after component updated
// has access of previous state and props with snapshot
// Can call methods here
// setState inside this will cause infinite loop
componentDidUpdate(prevProps, prevState, snapshot) {
console.log("componentDidUpdate: ", prevProps, prevState, snapshot);
}
static getDerivedStateFromError(error) {
console.log("getDerivedStateFromError");
return { hasError: true };
}
componentDidCatch(error, info) {
console.log("componentDidCatch: ", error, info);
}
// After component mount
// Good place to start AJAX call and initial state
componentDidMount() {
console.log("componentDidMount");
this.makeAjaxCall();
}
makeAjaxCall() {
console.log("makeAjaxCall");
}
onClick() {
console.log("state: ", this.state);
}
render() {
return (
<div style={{ border: "1px solid red", padding: "0px 10px 10px 10px" }}>
<p style={{ color: this.state.color }}>Color: {this.state.color}</p>
<button onClick={() => this.onClick()}>{this.props.value}</button>
</div>
);
}
}
// Parent component
class Parent extends React.Component {
constructor(props) {
super(props);
this.state = { value: 1 };
this.tick = () => {
this.setState({
date: new Date(),
value: this.state.value + 1
});
};
}
componentDidMount() {
setTimeout(this.tick, 2000);
}
render() {
return (
<div style={{ border: "1px solid blue", padding: "0px 10px 10px 10px" }}>
<p>Parent</p>
<Child value={this.state.value} />
</div>
);
}
}
function App() {
return (
<React.Fragment>
<Parent />
</React.Fragment>
);
}
const rootElement = document.getElementById("root");
ReactDOM.render(<App />, rootElement);
<div id="root"></div>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.6.3/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.6.3/umd/react-dom.production.min.js"></script>
score:62
If you use setState
inside componentDidUpdate
it updates the component, resulting in a call to componentDidUpdate
which subsequently calls setState
again resulting in the infinite loop. You should conditionally call setState
and ensure that the condition violating the call occurs eventually e.g:
componentDidUpdate: function() {
if (condition) {
this.setState({..})
} else {
//do something else
}
}
In case you are only updating the component by sending props to it(it is not being updated by setState, except for the case inside componentDidUpdate), you can call setState
inside componentWillReceiveProps
instead of componentDidUpdate
.
score:89
The componentDidUpdate
signature is void::componentDidUpdate(previousProps, previousState)
. With this you will be able to test which props/state are dirty and call setState
accordingly.
Example:
componentDidUpdate(previousProps, previousState) {
if (previousProps.data !== this.props.data) {
this.setState({/*....*/})
}
}
Source: stackoverflow.com
Related Query
- Maximum update depth exceeded. This can happen when a component repeatedly calls setState inside componentWillUpdate or componentDidUpdate
- Why is using setState inside componentDidUpdate seen as a bad practice in React?
- Error: Max update depth exceeded. This can happen when a component repeatedly calls setState inside componentWillUpdate or componentDidUpdate
- Error: Maximum update depth exceeded. This can happen when a component repeatedly calls setState inside componentWillUpdate or componentDidUpdate
- ReactJs: How to execute a function that depends on the result of a setState that's called inside componentDidUpdate
- I get error Maximum update depth exceeded. This can happen when a component repeatedly calls setState inside componentWillUpdate or componentDidUpdate
- ReactJS: setState on parent inside child component
- Event target is null inside functional setState
- How to test useEffect with async function and setState inside
- UI doesn't update until tap on the screen when setState is called inside a realm listener callback
- What is the advantage of using componentDidUpdate over the setState callback?
- How to do setState inside callback: ReactJS
- Will setState inside componentWillReceiveProps run before render?
- React setState inside of a function this is undefined
- React: How to use setState inside functional component?
- React Hooks: How to setState inside useEffect?
- React Context - setState with onClick inside Consumer
- this.state inside setState ReactJS
- setState inside Promise in React
- react-native - can't access setState inside component function
- Repeatedly calling setState inside componentWillUpdate or componentDidUpdate?
- setState call inside a custom hook is not updating the state
- setstate inside render method - Reactjs
- When does React re-render after a setState call made inside an event handler
- How to not use setState inside render function in React
- Can't call setState inside socket.io callback React.js
- React - setState inside componentDidMount
- ReactJS setState only works when nested inside setState
- setState inside promise.all() react
- ComponentDidUpdate SetState ReactJS Infinite loop
More Query from same tag
- Does React know not to re-render child when parent changes?
- In MUI when do we use Input vs. TextField for building a form?
- React native responsive header height
- How can I redirect from a class component?
- Update state from <select> tag using onChange and filter through list of categories to display blog posts from that category
- Render string containing JSX in react binding
- Converting array of object to hierarchical data structure
- Display a button when a checkbox is checked
- React delegate normal event handler to document, how about a binded function?
- React conditional rendering for nested if condition
- React BrowserRouter not working with nested path
- Not all the props that get passed down is rendered anyone have an idea as to why
- Material UI Paper background color based on elevation?
- How to perform multiple queries with Apollo graphql HOC?
- How to get children values on antd's form submit?
- componentDidMount() is not getting called but only in a particular circumstance
- delay css animation opacity in styled-components
- Invalid Hook Call in reactjs
- How to get the onChange() value from React Rrule Generator in TextInput field using React Admin
- React-hook-form conditional validation of text field, based on if another checkbox is checked?
- ReactTestUtils Simulate.Change parameter type SyntheticEventData error
- React scroll to top on page refresh - don't restore position
- How to make a div blinking cursor? react
- passing text box value to another React page in different page whereas shows in same page
- How to preload custom font face in react js?
- What if there is no opportunity to create unique keys?
- Cannot pass object data to modal
- React Router - Change state of other components
- Failed to compile is displayed on chrome browser
- Import index(.ts|.js) file from folder in React