-
Notifications
You must be signed in to change notification settings - Fork 5
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Unable to get clientWidth (always equals to 0) after upgrading to 2.3.0 #6
Comments
Hi @parachvte With React v16.3, you can try using node = React.createRef();
componentDidMount() {
// your parent element should have a pre-defined width and height
const { clientWidth, clientHeight } = this.node.current.parentElement;
}
render() {
return (
<div
ref={this.node}
/>
);
} |
It didn't help, using There is my code: getVisibleWidth() {
return this.node.current.parentElement.clientWidth;
}
componentDidMount() {
const width = this.getVisibleWidth();
console.log('width', width);
setTimeout(() => {
const width = this.getVisibleWidth();
console.log('width', width);
});
} Output:
I think there must be some render procedure changed that delayed the real render of my Component. |
The difference between 2.2.2 and 2.3.0 is the dependency update of React Portal component. In React 16, it will use ReactDOM.createPortal() API to wrap the children, not rendering elements to a new DOM node. import ReactDOM from 'react-dom';
import Portal from './Portal';
import LegacyPortal from './LegacyPortal';
export default !!(ReactDOM.createPortal) ? Portal : LegacyPortal; Portal.jsxhttps://github.com/trendmicro-frontend/react-portal/blob/master/src/Portal.jsx#L34-L39 render() {
return ReactDOM.createPortal(
this.props.children,
this.node
);
} LegacyPortal.jsxhttps://github.com/trendmicro-frontend/react-portal/blob/master/src/LegacyPortal.jsx#L37-L42 componentDidUpdate() {
ReactDOM.render(
this.props.children,
this.node
);
} There might be some differences after the change, but I think that is our call to fix deprecated code. |
I just took a look at your code and found some potential issues. You can see the article https://stackoverflow.com/questions/48323746/order-of-componentdidmount-in-react-components-hierarchy, it describes the order of componentDidMount in React components hierarchy. Let get back to your code when you finished the reading: class ExtractBgImg extends Component {
render() {
return (
<div style={{ height: '550px', width: '404px' }}>
<ExtractingPreview />
</div>
)
}
} ExtractBgImg's For a better approach, I suggest you use flexbox to control the layout: display: flex;
flex-direction: column; or pass down width and height through style or props to ExtractingPreview rather than accessing parent DOM node. That will make your code clean and elegant. |
Thanks @cheton I'll try flexbox later. I do know the render of parentNode comes after ExtractingPreview itself. |
You can get the size of the element with clientWidth or getBoundingClientRect().width. In some cases, I'm not quite sure why, clientWidth didn't work, but getBoundingClientRect did. So I get the width of the element in that order. I added a setTimeout because during rendering, the element may be adjusting to the layout, so it's important to be aware that its size may change depending on its CSS (or display of the scroll bar). React 18.2.0 import { useEffect, useRef } from "react"
import "./Component.scss"
function Component() {
const elementRef = useRef(null)
useEffect(() => {
const element = elementRef.current
let width = element.clientWidth || element.getBoundingClientRect().width
console.log(width)
setTimeout(() => {
width = element.clientWidth || element.getBoundingClientRect().width
console.log(width)
}, 1000)
}, [])
return (
<div id="component">
<div className="element" ref={elementRef}>element</div>
</div>
)
} |
Hi @cheton ,
After upgrading to 2.3.0, child components in
<Modal.Body>
are unable to get correct clientWidth oncomponentDidMount()
. It works good on version 2.2.2.The text was updated successfully, but these errors were encountered: