0

当我遇到一些障碍时,我一直在尝试做出反应并正在研究 react-grid-layout。我基本上按原样粘贴了这里的示例,但由于某种原因,当我拖动一个元素时它没有粘住。我在控制台中遇到的错误是:

Uncaught TypeError: this.props.onLayoutChange is not a function

我确信这是我缺少的一件简单的事情,但这是我的第一个 React 项目,我希望能得到一些指导。

我的代码包括在下面:

    'use strict';
    var React = require('react');
    var _ = require('lodash');
    var ResponsiveReactGridLayout = require('react-grid-layout').Responsive;

    /**
     * This layout demonstrates how to use a grid with a dynamic number of     elements.
     */
    var AddRemoveLayout = React.createClass({
    getDefaultProps() {
      return {
        className: "layout",
        cols: {lg: 12, md: 10, sm: 6, xs: 4, xxs: 2},
        rowHeight: 100
      };
    },

    getInitialState() {
      return {
        items: [0, 1, 2, 3, 4].map(function(i, key, list) {
          return {i: i, x: i * 2, y: 0, w: 2, h: 2, add: i === list.length -    1};
       }),
      newCounter: 0
      };
    },

    createElement(el) {
      var removeStyle = {
        position: 'absolute',
        right: '2px',
        top: 0,
        cursor: 'pointer'
      };
      var i = el.add ? '+' : el.i;
      return (
        <div key={i} _grid={el}>
          {el.add ?
            <span className="add text" onClick={this.onAddItem} title="You can add an item by clicking here, too.">Add +</span>
          : <span className="text">{i}</span>}
        <span className="remove" style={removeStyle} onClick={this.onRemoveItem.bind(this, i)}>x</span>
      </div>
    );
    },

    onAddItem() {
      console.log('adding', 'n' + this.state.newCounter);
      this.setState({
      // Add a new item. It must have a unique key!
      items: this.state.items.concat({
        i: 'n' + this.state.newCounter,
        x: this.state.items.length * 2 % (this.state.cols || 12),
        y: Infinity, // puts it at the bottom
        w: 2,
        h: 2
      }),
      // Increment the counter to ensure key is always unique.
      newCounter: this.state.newCounter + 1
    });
  },

  // We're using the cols coming back from this to calculate where to add new items.
  onBreakpointChange(breakpoint, cols) {
    this.setState({
      breakpoint: breakpoint,
      cols: cols
    });
  },

  onLayoutChange(layout) {
    this.props.onLayoutChange(layout);
    this.setState({layout: layout});
  },

  onRemoveItem(i) {
    console.log('removing', i);
    this.setState({items: _.reject(this.state.items, {i: i})});
  },

  render() {
    return (
      <div>
        <button onClick={this.onAddItem}>Add Item</button>
        <ResponsiveReactGridLayout onLayoutChange={this.onLayoutChange} onBreakpointChange={this.onBreakpointChange}
            {...this.props}>
          {_.map(this.state.items, this.createElement)}
        </ResponsiveReactGridLayout>
      </div>
    );
  }
});

module.exports = AddRemoveLayout;


React.render(<AddRemoveLayout/>, document.getElementById('app'))
4

3 回答 3

5

您收到的错误是关于缺少道具的错误。在 react 组件中,您基本上有 2 个位置来保存数据,在其父级和组件本身中。你的父母在声明它时经常有道具,因为这些是你传递给孩子的属性(如 HTML 标记中的属性)。然后我们有状态,它是组件本身内部的数据。

您收到的错误是说我们没有从父级获得所需的道具(您还可以看到在 onLayoutChange(layout) 函数内部正在调用 this.props.onLayoutChange(layout) 方法)

所以基本上我们缺少一些道具。在来自 GitHub 的示例中,有一个名为 test-hook.jsx ( https://github.com/STRML/react-grid-layout/blob/master/test/test-hook.jsx ) 的根文件。该根节点作为子节点(您尝试直接渲染的代码)在其中将所需的函数作为属性传递。

您可以使用 test-hook.jsx 或者您可以编写自己的根节点,该节点具有带有布局的状态和更新该状态的所需函数(有关如何执行此操作,请参见 github 示例)。

于 2015-11-10T15:23:20.120 回答
1

所以经过一番搜索,我发现该示例将 onLayoutChange 函数指定为占位符。如果我想要一个自定义函数,我需要定义它。

只需完全删除此功能并使用默认值即可解决问题。

删除这个:

onLayoutChange(layout) {
  this.props.onLayoutChange(layout);
  this.setState({layout: layout});
},
于 2015-11-10T15:48:41.717 回答
0

@Dirk-Jan 解释得很好。但恕我直言,正确的解决方案是删除道具调用:

onLayoutChange(layout) {
  // this.props.onLayoutChange(layout);
  this.setState({layout: layout});
},

所以有意义的部分仍然存在。在示例中, test-hook.jsx 父级必须获取布局,以便它可以将其显示在布局容器之外以进行演示。在现实世界的应用程序中,我们不需要它。

于 2016-07-14T07:28:10.587 回答