Hi, this is more like a question, I'd like to open a discussion regarding DOM manipulation in componentDidUpdate
.
I'm creating a React plugin. It has to do some DOM calculations, because CSS is not powerful enough to cover everything this plugin needs to do. The problem is I need to adjust some CSS properties depending on the return value of getBoundingClientRect() of some other DOM element rendered by the same component.
So technically we have 3 options:
1) Calculate getBoundingClientRect
in componentDidUpdate
and calling setState
with calculated values. I'm afraid of the infinite loop that could happen in certain cases, so I wouldn't go for this one.
2) Do it like in 1) and play a bit with shouldComponentUpdate
, but this seems very complex and not readable. A lot of questions pop up that are dependent on the certain use case.
3) Update DOM from componentDidUpdate. This is the solution I decided to go for, it works, it's simple, stable and works as intended. However I feel I'm on the edge, so I wanted to double check that this is an OK way of doing things. Is it OK to manipulate DOM in componentDidUpdate
? It's called everytime render
is done, and I'm OK with throwing away my changes, because for next render
I'll modify DOM again.
Here's a part of the code
componentDidMount() {
this.recalculateIndent();
}
componentDidUpdate() {
this.recalculateIndent();
}
recalculateIndent() {
// calculate indent based on getBoundingClientRect of some DOM reference
this.textareaRef.style.textIndent = `${indent}px`;
}
render() {
return (
...
<textarea ref={ref => this.textareaRef = ref}/>
...
);
}
Each solution (component lifecycle method) is proper for concrete situation, but DOM manipulation is wrong. Use state and re-render component. Example for my last use case "fixed header for table + virtual scrolling for table body", I hope this will help you understand the correct flow.
@jvorcak using componentDidUpdate
is the correct place to manipulate the DOM manually after a render. Per the docs:
Use this as an opportunity to operate on the DOM when the component has been updated.
Also, we try to use the issue tracker solely for feature requests and bug reports. Usage questions should be directed elsewhere, like discuss.reactjs.org or StackOverflow. Thanks!
What if you want to update one Component after changing something in another?
Most helpful comment
@jvorcak using
componentDidUpdate
is the correct place to manipulate the DOM manually after a render. Per the docs:Also, we try to use the issue tracker solely for feature requests and bug reports. Usage questions should be directed elsewhere, like discuss.reactjs.org or StackOverflow. Thanks!