手感&反应

Handsontable & React

我从 React 开始,并尝试在我的 React 应用程序中设置 handsontable,如下所示: react-handsontable

// import React...
import React from 'react';
import ReactDOM from 'react-dom';

// ... Handsontable with its main dependencies...
import moment from 'moment';
import numbro from 'numbro';
import pikaday from 'pikaday';
import Zeroclipboard from 'zeroclipboard';
import Handsontable from 'handsontable';

// ... and HotTable
import HotTable from 'react-handsontable';

class ExampleComponent extends React.Component {
  constructor(props) {
    super(props);
    this.handsontableData = [
      ["", "Ford", "Volvo", "Toyota", "Honda"],
      ["2016", 10, 11, 12, 13],
      ["2017", 20, 11, 14, 13],
      ["2018", 30, 15, 12, 13]
    ];
  }

  render() {
    return (
      <div id="example-component">
        <HotTable root="hot" data={this.handsontableData} colHeaders={true} rowHeaders={true} width="600" height="300" stretchH="all" />
      </div>
    );
  }
}

目前有效,但我如何获得 table 的实例,就像在纯 javascript

中一样
var ht = new Handsontable(document.getElementById('example1'), options);


ht.setDataAtCell(0, 0, 'new value');

谢谢,提姆

您将数据作为构造函数中定义的数组。

this.handsonetableData = [[First row],[second row]]

您可以简单地 link 将该数据添加到组件中的状态和 setState 中。它应该非常简单。

this.state = {
  table: [[first line], [second line]]
}

最终,您可以编写自己的方法来更新该数组的特定值。

constructor (props) {
  super(props)
  this.state = {
    table: [[first row], [second row]]
  }
}
updateValueInTable (row, col, value)
  checkIdontDoAnythingStupid()
  let newTable = this.state.table
  newTable[row][col] = value
  this.setState({ table: newTable})
}

如果您不想使用状态并使用类似 redux 的东西,您可以将逻辑放在 reducer 中,将触发器放在操作中。你来了!

当然取决于您如何检查您是否正确操作了数组,很多库都可以提供帮助(lodash 和合作伙伴)

为 handsontable 编写自己的反应包装器非常简单,然后您可以创建对 HOT 实例的引用。这是一些示例 React 组件代码:

componentWillReceiveProps({ gridSpec }) {

     if (gridSpec) {
        const {columns, colHeaders, data} = gridSpec;
        const container = document.getElementById(GRID_ID);

        this.hotInstance = new handsontable(container, {
            columns,
            colHeaders,
            data,
            height: 600
        });
    }
}

shouldComponentUpdate () {

    return false;
 }

render () {
    return (
        <div style={{overflowX: 'hidden', height: '600px'}}>
            <div id={GRID_ID} />
        </div>
    )
}

如果您尝试访问核心方法,例如 'setDataAtCell()',您可以使用 refs 来访问它们。

例如,将 "ref='xyz'" 属性添加到 HTML 元素,然后您可以使用 "this.refs.xyz" 调用它。我在下面修改了您的示例以进行说明。它向'setDataAtCell'.

添加了一个onClick运行函数的按钮
// import React...
import React from 'react';
import ReactDOM from 'react-dom';

// ... Handsontable with its main dependencies...
import moment from 'moment';
import numbro from 'numbro';
import pikaday from 'pikaday';
import Zeroclipboard from 'zeroclipboard';
import Handsontable from 'handsontable';

// ... and HotTable
import HotTable from 'react-handsontable';

class ExampleComponent extends React.Component {
  constructor(props) {
    super(props);
    this.handsontableData = [
      ["", "Ford", "Volvo", "Toyota", "Honda"],
      ["2016", 10, 11, 12, 13],
      ["2017", 20, 11, 14, 13],
      ["2018", 30, 15, 12, 13]
    ];
  }

  handleClick(e) {
    this.refs.hot.hotInstance.setDataAtCell(0, 0, 'new value')
  }

  render() {
    return (
      <div id="example-component">
        <HotTable root="hot"
                  data={this.handsontableData}
                  colHeaders={true}
                  rowHeaders={true}
                  width="600"
                  height="300"
                  stretchH="all"
                  ref="hot"
        />
        <br/>
        <button onClick={(e)=>this.handleClick(e)}>Click Me</button>
      </div>
    );
  }
}

export default ExampleComponent

此方法可用于访问其他方法,如 "getData()",可用于获取 table 中数据的快照,可将其保存到状态或类似内容。所以它比 "ht" 更长,你可以使用 "this.refs.hot.hotInstance" 来达到类似的效果。

您可以在 React 文档的“Refs and the DOM”中阅读有关 ref 属性的更多信息。

要访问 HotTable 组件的实例,请使用 ref。但是,不要使用使用 ref 的旧方法。从版本 16.3 开始,React 提供了 2 种方式:

  • 使用 createRef API 这是推荐的方式
  • 使用回调引用 这在早期版本中已经可用,但比 旧 "string ref" 方式。

我在这里只展示如何使用 createRef :

  1. 在您的构造函数中,添加以下内容:

    this.refToHotIns=React.createRef();
    

    字段的名称属性任意,你可以随意命名。

  2. 在您的 render() 方法中,将 JSX 元素更改为:

       <HotTable ref={this.refToHotIns} data={this.handsontableData} colHeaders={true} rowHeaders=true} width="600" height="300" stretchH="all" />
    
  3. 现在,this.refToHotIns.current 引用已安装的 HotTable 实例。 Handsontable 实例存储在包装器组件的 hotInstance 属性 下。因此,您可以访问 HotTable 实例的 properties/methods,如下所示:

    this.refToHotIns.current.hotInstance.setDataAtCell(0, 0, 'new value');