I have a component where there are draggable components inside with translate applied for the drag&drop and a default translation when it's rendered depending on parent's height and width to keep the ratio.
When I resize the window, the parent component change size so the components inside have to re-render to reset the default translation based on the parent size. I pass the size props to the child's but they do not rerender, I believe this is because the translation is done straight in the style attribute.
So I made a trick to force re-render, I pass the props key to the wrapper where the value is the height multiplicate by a width which makes a unique key, change on resizing and then rerender my components with the right default position. Here is what it looks like :
render() {
const { height, width, frame, elem } = this.state;
const key = height * width;
return (
<WrapperFrame>
<WrapperMediaElem key={frame.id}>
<WrapperElements key={key} className="droppable" size={{height, width}}>
<DraggableElement element={{...elem}} size={{height, width}} />
</WrapperElements>
</WrapperMediaElem>
</WrapperFrame>
);
}
This solution works for me but it looks like a "trick" and maybe not the good approach. I wanted to know if it's the right way or if is there a better solution?
Related
I'm using DetalisList within ScrollablePane component to keep the header in view, and let the rows scrollable. However, this requires me to manually set the height of the scrollable container.
div.scrollable-container
ScrollablePane
DetailsList
When I investigate the DOM elements for DetalisList, I can see that it's wrapped inside a ViewPort element. The height of this element is the actual height of the sum of the height of all components that make up the list (column headers, rows. etc.). Thus, I want to be able to read this value and set the container height based on whether it exceeds a certain value or not.
Is there a nice to way to access the height of the ViewPort? I can always query the DOM, and find the element, but I'd like to avoid relying on the internal structure of the component.
So, far I could not find any information on this. I noticed DetailsList takes a prop called viewport, but I don't think this is what I want.
You can try by giving height in "vh" (viewport height) unit. For example,
const gridContainerStyle: IStackStyles = {
root: { height: "70vh", position: "relative" },
};
I'm developing a numerical Slider component in React. It actually works right now and is fully functional, but there is a single issue. I set the width of the thumb and total slider via CSS, and I like doing it that way, as it's flexible.
The slider and thumb width is also needed for calculations, such as calculating the max position of the slider, or the position of the thumb relative to the absolute.
So, I have functions like this:
getSliderWidth = () => {
return this.sliderRef.current ? this.sliderRef.current.offsetWidth : 0;
}
getThumbWidth = () => {
return this.sliderThumbRef.current ? this.sliderThumbRef.current.clientWidth : 0;
}
Where the refs are defined in the render function like so:
<div ref={this.sliderRef} className="slider-range">
<div className="slider-range-connect" style={connectStyle}></div>
<div ref={this.sliderThumbRef} className="slider-range-thumb" style={thumbStyle}></div>
</div>
The issue with this, though, is that the widths are only known after the first render. The refs aren't available until it is first rendered. So, I think what I need to do is force a re-render, such that when the component is initially loaded, it is rendered one more time. This is because the initial render function needs to know the relative max position and thumb position in order to render the initial elements.
So, is there a "React" way to do this, or am I missing something? Is the ideal solution here to have some sort of boolean flag, and in the initial mount function, to check this flag, and if it is the first render, to do another render, and then to set the flag? That doesn't seem very "React"ish, so I was wondering if there is something more elegant.
I need to get the available height between the top and bottom elements. Currently, I am calculating it by
screenHeight - statusBarHeight - topElementHeight - bottomElementHeight.
This method is working, but I always have to look up if all the top and bottom elements are visible and account for that.
Is there any better method of getting this height?
Place a View element in between top and bottom elements and use onLayout prop to receive dimensions of this View.
render() {
<TopComponent />
<View onLayout={this.measureView} />
<BottomComponent />
}
measureView = (event) => {
console.log(event.nativeEvent.layout.height)
}
Make sure that the View occupies the entire space between top and bottom elements. You can use flexbox or absolute positioning for that depending on your current layout.
I need to set component dimensions depending on parent element. Is it possible to get width and height of parent by ref from virtualDOM before it renders?
Parent
export default class App extends React.Component {
render() {
return (
<div>
<div className={'avocado-container'} ref={(container) => { this.container = container; }}>
<Resizer parent={this} scrollAxis={'y'}>
</Resizer>
</div>
</div>
);
}
}
I need to get the dimensions in constructor of child.
Is is possible with something like this.refs.container.offsetWidth ?
No. Layout dimensions are calculated by the browser, not the Virtual DOM. Either set the dimensions by hand, or use CSS to make your child component fill width and height. You can also read the width and height from the rendered component in componentDidMount and call setState in there, which isn't ideal and will cause a second render, but sometimes needs to be done.
I have a complex web page using React components, and am trying to convert the page from a static layout to a more responsive, resizable layout. However, I keep running into limitations with React, and am wondering if there's a standard pattern for handling these issues. In my specific case, I have a component that renders as a div with display:table-cell and width:auto.
Unfortunately, I cannot query with width of my component, because you can't compute the size of an element unless it's actually placed in the DOM (which has the full context with which to deduce the actual rendered width). Besides using this for things like relative mouse positioning, I also need this to properly set width attributes on SVG elements within the component.
In addition, when the window resizes, how do I communicate size changes from one component to another during setup? We're doing all of our 3rd-party SVG rendering in shouldComponentUpdate, but you cannot set state or properties on yourself or other child components within that method.
Is there a standard way of dealing with this problem using React?
The method of lifecycle you probably want is componentDidMount
The elements have already been placed in the DOM and you can get information about them from the component's refs.
Example:
var Container = React.createComponent({
componentDidMount: function () {
var width = this.refs.svg.getDOMNode().offsetWidth;
},
render: function () {
<svg ref="svg" />
}
});
In componentDidMount you can get the window.width or ReactDom.findDOMNode(this).width. Then use the width in state and pass as a prop as needed. You can also set a listener for the resize event.