首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >以编程方式更改react-grid-layout中项目的高度/宽度

以编程方式更改react-grid-layout中项目的高度/宽度
EN

Stack Overflow用户
提问于 2016-02-29 06:52:13
回答 2查看 11.3K关注 0票数 13

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

但是,在初始渲染之后,该库似乎会忽略对layout的更改。这是真的吗,还是我这头有个bug?如果这是正常行为,是否有其他方法可以通过编程更改高度?

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

jsFiddle example

代码语言:javascript
复制
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;
EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2016-03-05 02:16:58

事实证明,诀窍是不使用_grid,而是使用Grid组件上的layout prop。下面是一个有效的jsfiddle:

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

和代码:

代码语言:javascript
复制
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'));
票数 6
EN

Stack Overflow用户

发布于 2021-12-26 20:32:03

多亏了@aepp's elaboration on Github,这个解决方案运行良好,我已经使用react-grid-layout@1.3.0对其进行了测试

代码语言:javascript
复制
import React, {Component} from 'react';
import GridLayout from 'react-grid-layout';

...

//defining the layout inside the "state"
constructor(props) {
  super(props);

  this.state = {
    layout: [
      ...your_grid_items
    ],
  };
}

...

resizeGridItem = () => {
  const layout = this.state.layout.map(item => {...item});
  //here you can modify your layout, i.e.
  //layout[4].h = 4;
  ...

  this.setState({layout});
}

...

render() {
  return (
    <div>
      <GridLayout
        layout={this.state.layout}
        ...
      >
        ...
      </GridLayout>
      ...
      <button onClick={this.resizeGridItem}>Resize</button>
    </div>
  );
}
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/35689302

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档