有没有办法以编程方式更改项目布局的 wh ?用例是有一个“折叠”按钮,可将高度降低到恒定高度,足以留下项目的标题。为此,我最初的想法是将布局保持在组件的状态,并手动将折叠项目的高度更改为另一个恒定高度。

但是,该库似乎会忽略初始渲染后对布局的更改。是这种情况还是我这边的错误?如果这是正常行为,是否有另一种方法可以以编程方式改变高度?

这是一个实现react-grid-layout的独立组件。这是两个“小部件”,有一个 onClick 处理程序来“折叠”它们。通过设置状态,它会触发重新渲染并重新计算布局,以便任何折叠的项目都具有减小的高度。控制台日志语句显示渲染的组件具有正确的新布局,但它没有反射(reflect)在屏幕上,使我相信还有另一个对高度的引用。

jsFiddle example

import React, { Component } from 'react'; 
 
import GridLayout, { WidthProvider } from 'react-grid-layout'; 
const Grid = WidthProvider(GridLayout); 
 
// # WidgetsContainer 
// Container WidgetsContainer component. 
class WidgetsContainer extends Component { 
 
    static defaultProps = { 
        isDraggable: true, 
        isResizable: true, 
        rowHeight: 1, 
        cols: 12, 
    } 
 
    constructor(props) { 
        super(props); 
        this.state = { 
            layouts: [ 
                { 
                    i: 'item_1', 
                    x: 0, 
                    y: 0, 
                    w: 5, 
                    h: 25, 
                }, { 
                    i: 'item_2', 
                    x: 5, 
                    y: 0, 
                    w: 7, 
                    h: 30, 
                }, 
            ], 
            collapsedWidgets: {}, 
        }; 
    } 
 
    toggleWidget(id) { 
        return () => { 
            const newState = {...this.state.collapsedWidgets}; 
            const collapsed = typeof newState[id] === 'boolean' ? newState[id] : false; 
 
            newState[id] = !collapsed; 
            this.setState({ 
                collapsedWidgets: newState, 
            }); 
        } 
 
    } 
 
    onResize(layouts) { 
        this.setState({ 
            layouts, 
        }); 
    } 
 
    getModifiedLayouts() { 
        const { layouts, collapsedWidgets } = this.state; 
 
        const newLayouts = layouts.map(layout => { 
            const newLayout = { ...layout }; 
            if (collapsedWidgets[newLayout.i]) { 
                newLayout.h = 5; 
            } 
            return newLayout; 
        }); 
 
        return newLayouts; 
    } 
 
    getWidgets() { 
        const widgets = [{ 
            component: <div style={{ height: '250px', background: 'lightgray' }}>Content</div>, 
            title: 'Item 1', 
            id: 'item_1', 
        }, { 
            component: <div style={{ height: '310px', background: 'lightgray' }}>Content 2</div>, 
            title: 'Item 2', 
            id: 'item_2', 
        }]; 
        return widgets; 
    } 
 
    generateDOM() { 
        const widgets = this.getWidgets(); 
 
        const modifiedLayouts = this.getModifiedLayouts(); 
 
        return widgets.map((widget, i) => { 
            return (<div key={i} _grid={modifiedLayouts[i]}> 
                <div style={{ background: 'gray' }} onClick={::this.toggleWidget(widget.id)}> 
                    {widget.title} 
                    {widget.component} 
                </div> 
            </div>); 
        }); 
    } 
 
    render() { 
        const widgets = this.generateDOM(); 
        console.log(widgets[0].props._grid) 
        return (<div style={{ marginTop: '15px' }}> 
                {widgets ? <Grid className="layout" 
                  {...this.props} 
                  onResizeStop={::this.onResize} 
                > 
                    {widgets} 
                </Grid> : null} 
            </div>); 
    } 
} 
 
export default WidgetsContainer; 

请您参考如下方法:

事实证明,技巧是不使用 _grid 而是使用 Grid 组件上的 layout 属性。这是一个工作的 jsfiddle:

http://jsfiddle.net/zekedroid/d9o75d24/

代码:

const Grid = ReactGridLayout.WidthProvider(ReactGridLayout); 
 
class Logo extends React.Component { 
    constructor(props) { 
        super(props); 
        this.state = { 
            layouts: [ 
                { 
                    i: '0', 
                    x: 0, 
                    y: 0, 
                    w: 5, 
                    h: 25, 
                }, { 
                    i: '1', 
                    x: 5, 
                    y: 0, 
                    w: 7, 
                    h: 30, 
                }, 
            ], 
            collapsedWidgets: {}, 
        }; 
    } 
 
    toggleWidget(id) { 
        return () => { 
            const newState = {...this.state.collapsedWidgets}; 
            const collapsed = typeof newState[id] === 'boolean' ? newState[id] : false; 
 
            newState[id] = !collapsed; 
            this.setState({ 
                collapsedWidgets: newState, 
            }); 
        } 
 
    } 
 
    onResize(layouts) { 
        this.setState({ 
            layouts, 
        }); 
    } 
 
    getModifiedLayouts() { 
        const { layouts, collapsedWidgets } = this.state; 
 
        const newLayouts = layouts.map(layout => { 
            const newLayout = { ...layout }; 
            if (collapsedWidgets[newLayout.i]) { 
                newLayout.h = 5; 
            } 
            return newLayout; 
        }); 
 
        return newLayouts; 
    } 
 
    getWidgets() { 
        const widgets = [{ 
            component: <div style={{ height: '250px', background: 'lightgray' }}>Content</div>, 
            title: 'Item 1', 
            id: '0', 
        }, { 
            component: <div style={{ height: '310px', background: 'lightgray' }}>Content 2</div>, 
            title: 'Item 2', 
            id: '1', 
        }]; 
        return widgets; 
    } 
 
    generateDOM() { 
        const widgets = this.getWidgets(); 
 
        return widgets.map((widget, i) => { 
            return (<div key={i} style={{ overflowY: 'auto' }}> 
                <div style={{ background: 'gray' }} onClick={this.toggleWidget(widget.id).bind(this)}> 
                    {widget.title} 
                    {widget.component} 
                </div> 
            </div>); 
        }); 
    } 
 
    render() { 
        const widgets = this.generateDOM(); 
 
        const modifiedLayouts = this.getModifiedLayouts(); 
 
        return (<div style={{ marginTop: '15px' }}> 
                {widgets ? <Grid className="layout" 
                  {...this.props} 
                  onResizeStop={this.onResize.bind(this)} 
                  layout={modifiedLayouts} 
                > 
                    {widgets} 
                </Grid> : null} 
            </div>); 
    } 
} 
 
Logo.defaultProps = { 
        isDraggable: true, 
        isResizable: true, 
        rowHeight: 1, 
        cols: 12, 
    } 
 
 
 
React.render( <Logo /> , document.getElementById('container')); 


评论关闭
IT虾米网

微信公众号号:IT虾米 (左侧二维码扫一扫)欢迎添加!