On initial page load or browser resize offsetWidth is correct, however if there is a change to the DOM which adjusts the parent width it is not correct.
I started with my sidebar expanded and the parent offsetWidth at 1298. When I collapse my sidebar the onWindowResize function is called and the offsetWidth now shows 1148 but ReactDOM.findDOMNode(this) isn't pulling the latest.
Steps To Reproduce
sampleSidebar resize trigger $(window).resize();sampleSidebar which causes parent to change width rather than browser resizeonWindowResize is called but node.clientWidth is previous size.onSidebarToggle = () => {
...code that toggles size
$(window).resize();
}
onWindowResize = () => {
this.calculateWidth()
}
calculateWidth = () => {
if (!this.mounted) return
let node = ReactDOM.findDOMNode(this);
console.log(`clientWidth: ${node.clientWidth}`);
console.log(node);
if (node instanceof HTMLElement) {
this.setState({ width: node.offsetWidth })
}
}

FYI the link to WebpackBin Template isn't working.
I was able to find a way around this similar to what is mentioned in #607 and #608. The issue is that I'm using a short animation on my element resizing and calculateWidth is called immediately. I solved this by adding a very short timeout.
onWindowResize = () => {
setTimeout(() => {
this.calculateWidth()
}, 200)
}
If I submit a PR for this fix, would it be possible to update WidthProvider out of the box to accept a timeout? I would imagine that a lot of people use animations.
Tried an initial stab at a PR but I'm running into the following error.
Error: lib/components/WidthProvider.jsx:68
68: }, delay)
^^^^^ delay. Could not resolve name
Here is my updated WidthProvider.jsx
// @flow
import React from "react";
import PropTypes from "prop-types";
import ReactDOM from "react-dom";
import type { ComponentType as ReactComponentType } from "react";
type WPProps = {
className?: string,
measureBeforeMount: boolean,
delay: number,
style?: Object
};
type WPState = {
width: number
};
/*
* A simple HOC that provides facility for listening to container resizes.
*/
export default function WidthProvider<
Props,
ComposedProps: { ...Props, ...WPProps }
>(
ComposedComponent: ReactComponentType<Props>
): ReactComponentType<ComposedProps> {
return class WidthProvider extends React.Component<ComposedProps, WPState> {
static defaultProps = {
measureBeforeMount: false,
delay: 0
};
static propTypes = {
// If true, will not render children until mounted. Useful for getting the exact width before
// rendering, to prevent any unsightly resizing.
measureBeforeMount: PropTypes.bool,
delay: PropTypes.number
};
state = {
width: 1280
};
mounted: boolean = false;
componentDidMount() {
this.mounted = true;
window.addEventListener("resize", this.onWindowResize);
// Call to properly set the breakpoint and resize the elements.
// Note that if you're doing a full-width element, this can get a little wonky if a scrollbar
// appears because of the grid. In that case, fire your own resize event, or set `overflow: scroll` on your body.
this.onWindowResize();
}
componentWillUnmount() {
this.mounted = false;
window.removeEventListener("resize", this.onWindowResize);
}
onWindowResize = () => {
setTimeout(() => {
if (!this.mounted) return;
// eslint-disable-next-line
const node = ReactDOM.findDOMNode(this); // Flow casts this to Text | Element
if (node instanceof HTMLElement)
this.setState({ width: node.offsetWidth });
}, delay)
};
render() {
const { measureBeforeMount, delay, ...rest } = this.props;
if (measureBeforeMount && !this.mounted) {
return (
<div className={this.props.className} style={this.props.style} />
);
}
return <ComposedComponent {...rest} {...this.state} />;
}
};
}
@CWSites I have a issue like yours.
let event = new CustomEvent("resize");
window.dispatchEvent(event);
I add above code into my relate component.
@linmodev did that fix the error? Where in the code did you add that to?
componentDidUpdate() {
let event = new CustomEvent("resize");
window.dispatchEvent(event);
}
This is not a nice solution. But I solve the item component is out of parent's range.
@CWSites
@linmodev why don't you submit a PR with this change? It seems much more straight forward than mine if it works.
@CWSites But these code is not insert component source code, I just add this code to some place it needs.So it not a real final solution.
I'm having the exact same issue, and even in a manual window resize, the width value in widthProvider is not updated.
Any new thoughts ?