将动态生成的复选框添加到 react-table 并捕获行数据

Posted

技术标签:

【中文标题】将动态生成的复选框添加到 react-table 并捕获行数据【英文标题】:Adding dynamically generated checkboxes to react-table and capturing row data 【发布时间】:2018-03-15 01:50:39 【问题描述】:

我在使用这个 react-table 包https://react-table.js.org/#/story/readme向行添加复选框时遇到了麻烦

我正在尝试为表格中的每一行添加一个复选框。我尝试将“复选框”添加到列区域中看到的“单元格”值,但是,它似乎不适用于分页。一旦我单击下一页然后返回,它就会忘记所有以前检查过的产品。我如何保持它们的状态?

我添加了一个键,它可以防止在所有页面上检查该元素,但是当我在页面上来回切换时它不会记住它。所以我现在只需要存储它的“开启状态”。

Cell: rowInfo => (<Checkbox key=rowInfo.index onChange=this.handleChange />)

这是完整的代码:

import React from 'react'
import ReactDOM from 'react-dom'
import ReactTable from 'react-table'
import PropTypes from 'prop-types'
import  Checkbox  from '@shopify/polaris';

export default class ProductIndexTable extends React.Component 
  constructor(props) 
    super(props);
    this.state = 
     rowInfo: '' 
    
    this.handleChange = this.handleChange.bind(this)
  
  handleChange(event) 
  
  render() 
    function CreateItem(product) 
      return  
        title: <a href='/products/' + product.id >product.title</a>,
        price_test_status: product.has_active_price_test,
        price_test_completion_percentage: product.price_test_completion_percentage
      
    
  return (<ReactTable
            data=this.props.products.map(CreateItem)
            getTdProps=(state, rowInfo, column, instance) => 
              return 
                onClick: (e, handleOriginal) => 
                  // console.log('A Td Element was clicked!')
                  // console.log('it produced this event:', e)
                  // console.log('It was in this column:', column)
                  // console.log('It was in this row:', rowInfo)
                  // console.log('It was in this table instance:', instance)
                  this.setState(
                    rowInfo: rowInfo.index
                  )
                  // IMPORTANT! React-Table uses onClick internally to trigger
                  // events like expanding SubComponents and pivots.
                  // By default a custom 'onClick' handler will override this functionality.
                  // If you want to fire the original onClick handler, call the
                  // 'handleOriginal' function.
                  if (handleOriginal) 
                    handleOriginal()
                  
                
              
            
            columns=[
            
              Header: "Base",
              columns: [
                
                  Header: <Checkbox />,
                  maxWidth: 50,
                  Cell: (<Checkbox onChange=this.handleChange />)
                , 
                  Header: "Product Title",
                  accessor: "title",
                  maxWidth: 400
                , 
                  Header: "Price Test Status",
                  accessor: "price_test_status",
                  maxWidth: 200
                , 
                  Header: "Price Test Completion Percentage",
                  accessor: "price_test_completion_percentage",
                  Cell: row => (
                    <div
                      style=
                        width: '100%',
                        height: '100%',
                        backgroundColor: '#dadada',
                        borderRadius: '2px'
                      
                    >
                    <div
                      style=
                        width: `$row.value%`,
                        height: '100%',
                        backgroundColor: row.value > 66 ? '#85cc00'
                          : row.value > 33 ? '#ffbf00'
                          : '#ff2e00',
                        borderRadius: '2px',
                        transition: 'all .2s ease-out'
                      
                    />
                    </div>
                  )
                
              ]
            
            ]
            defaultPageSize=10
            className="-striped -highlight"
          />
  );

【问题讨论】:

你试过在复选框上使用key 属性吗? 您可以尝试在这里提出问题:github.com/react-tools/react-table/issues,因为这听起来像是包中的错误 好主意。刚刚提出这个问题。我仍然想知道是否有解决方法?我还没有尝试使用密钥道具。我是新手,所以我必须对此进行一些研究。 @ByteMe 只需添加 key 属性并放置一个唯一的 id,它可以是地图函数中的计数器。当它们都在虚拟 DOM 中时,React 使用它来区分相同的组件 感谢 Carlos,我添加了 key 道具,它阻止了它检查其他页面上的所有元素。我现在只需要弄清楚如何存储它们。查看我的更新 【参考方案1】:

我最终在单击时将标题存储到哈希中,这给了我最终的解决方案。它检查哈希状态以查看该值是否为真,并应保持检查状态。请参阅下面的代码。希望它可以帮助别人!还要检查我用来帮助我的 codepen 示例。

https://codepen.io/aaronschwartz/pen/WOOPRw?editors=0010

import React from 'react'
import ReactDOM from 'react-dom'
import ReactTable from 'react-table'
import PropTypes from 'prop-types'
import  Checkbox  from '@shopify/polaris';

export default class ProductIndexTable extends React.Component 
  constructor(props) 
    super(props);
    this.state = 
     selected: ,
     selectAll: 0,
     products: this.props.products
    
    this.toggleRow = this.toggleRow.bind(this);
  
    toggleRow(title) 
        const newSelected = Object.assign(, this.state.selected);
        newSelected[title] = !this.state.selected[title];
        this.setState(
            selected: newSelected,
            selectAll: 2
        );
    
    toggleSelectAll() 
        let newSelected = ;
        if (this.state.selectAll === 0) 
            this.state.products.forEach(x => 
                newSelected[x.title] = true;
            );
        
        this.setState(
            selected: newSelected,
            selectAll: this.state.selectAll === 0 ? 1 : 0
        );
    

  render() 
    function CreateItem(product) 
      return  
        title: <a href='/products/' + product.id >product.title</a>,
        price_test_status: product.has_active_price_test,
        price_test_completion_percentage: product.price_test_completion_percentage
      
    
  return (<ReactTable
            data=this.props.products.map(CreateItem)
            columns=[
            
              Header: "Base",
              columns: [
                
                            id: "checkbox",
                            accessor: "",
                            Cell: ( rowInfo ) => 
                                return (
                                    <Checkbox
                                        type="checkbox"
                                        className="checkbox"
                                      checked=this.state.selected[rowInfo.original.title.props.children] === true
                                        onChange=() => this.toggleRow(rowInfo.original.title.props.children)
                                    />
                                );
                            ,
                            Header: title => 
                                return (
                                    <Checkbox
                                        type="checkbox"
                                        className="checkbox"
                                        checked=this.state.selectAll === 1
                                        ref=input => 
                                            if (input) 
                                                input.indeterminate = this.state.selectAll === 2;
                                            
                                        
                                        onChange=() => this.toggleSelectAll()
                                    />
                                );
                            ,
                            sortable: false,
                            width: 45
                        ,                
                
                  Header: "Product Title",
                  accessor: "title",
                  maxWidth: 400
                , 
                  Header: "Price Test Status",
                  accessor: "price_test_status",
                  maxWidth: 200
                , 
                  Header: "Price Test Completion Percentage",
                  accessor: "price_test_completion_percentage",
                  Cell: row => (
                    <div
                      style=
                        width: '100%',
                        height: '100%',
                        backgroundColor: '#dadada',
                        borderRadius: '2px'
                      
                    >
                    <div
                      style=
                        width: `$row.value%`,
                        height: '100%',
                        backgroundColor: row.value > 66 ? '#85cc00'
                          : row.value > 33 ? '#ffbf00'
                          : '#ff2e00',
                        borderRadius: '2px',
                        transition: 'all .2s ease-out'
                      
                    />
                    </div>
                  )
                
              ]
            
            ]
            defaultPageSize=10
            className="-striped -highlight"
          />
  );

【讨论】:

Codepen 示例与您的代码无关【参考方案2】:

要解决所有页面中的项目检查问题,只需在&lt;Checkbox /&gt;组件上添加key属性即可。

现在,关于存储状态的问题,我们讨论了多少个复选框?您的状态应该有一个数组,带有所有复选框,一旦选中一个复选框,您就可以发送 ID(key 道具,这可能是.map() 上的计数器)并将数组的位置设置为真或假(选中或未选中)

【讨论】:

产品的数量可能会有所不同,因此复选框的数量也会有所不同。我试图弄清楚如何创建一个状态数组并实现它。 您可以将键添加到数组中,并在取消选中时将其删除,并在每次选中/取消选中时将数组设置为状态。试图想出更好的解决方案。

以上是关于将动态生成的复选框添加到 react-table 并捕获行数据的主要内容,如果未能解决你的问题,请参考以下文章

动态更新 react-table 中可用记录数的计数

PHP、动态表单、访问 POST 变量、复选框

将复选框动态添加到 Windows 窗体仅显示一个复选框

将复选框动态添加到列表视图

如何将事件侦听器添加到动态创建的复选框并检查是不是选中了复选框。 JavaScript

react-table 在数据中渲染组件