React - 将数据映射到在映射函数期间形成的行

React - mapping data to rows that are formed during a map function

我有一个名为 Cells 的组件,它使用从通量存储中获取的数据进行渲染。我的问题是我想将此数据呈现到特定行,但由于我呈现行的方式(它们是动态的,因此您可以将它们添加到 table),我很难为行提供标识符单元格组件可以渲染到其中。我希望这是有道理的!

代码如下:

单元格组件:

import React from 'react';

export default class Cells extends React.Component {
    render() {
        return (
            <td>{this.props.value}</td>
        );
    }
}

Table 分量:

    import React from 'react';
    import TableHeader from './TableHeader.jsx';
    import Cells from './Cells.jsx';
    import RowForm from './RowForm.jsx';
    import {createRow} from '../../actions/DALIActions';
    import AppStore from '../../stores/AppStore';

    export default class Table extends React.Component {
        state = {rows: [], cellValues: [], isNew: false, isEditing: false};
        updateState = () => this.setState({cellValues: AppStore.getCellValues()});

        componentWillMount() {
            AppStore.addChangeListener(this.updateState);
        }

        handleAddRowClickEvent = () => {
            let rows = this.state.rows;
            rows.push({isNew: true});
            this.setState({rows: rows});
        };

        handleEdit = (row) => {
            this.setState({isEditing: true});
        };

        editStop = () => {
            this.setState({isEditing: false});
        };

        handleSubmit = (access_token, id, dataEntriesArray) => {
            createRow(access_token, id, dataEntriesArray);
        };

        componentWillUnmount() {
            AppStore.removeChangeListener(this.updateState);
        }

        render() {

            let {rows, cellValues, isNew, isEditing} = this.state;

            let headerArray = AppStore.getTable().columns;

            let cells = this.state.cellValues.map((value, index) => {
                return (
                    <Cells key={index} value={value.contents} />
                );
            });

            return (
                <div>
                    <div className="row" id="table-row">
                        <table className="table table-striped">
                            <thead>
                                <TableHeader />
                            </thead>
                            <tbody>
//////////// This is where the render of the data would happen/////////////
                                {rows.map((row, index) => this.state.isEditing ?
                                    <RowForm formKey={index} key={index} editStop={this.editStop} handleSubmit={this.handleSubmit} /> :
                                    <tr key={index}>
                                        {this.state.cellValues ? cells : null}
                                        <td>
                                            <button className="btn btn-primary" onClick={this.handleEdit.bind(this, row)}><i className="fa fa-pencil"></i>Edit</button>
                                        </td>
                                    </tr>
                                )} 
                   ///////////////End/////////////////
                            </tbody>
                        </table>
                    </div>
                    <div className="row">
                        <div className="col-xs-12 de-button">
                            <button type="button" className="btn btn-success" onClick={this.handleAddRowClickEvent}>Add Row</button>
                        </div>
                    </div>
                </div>
            );
        }
    }

我知道这可能不是实现我想要的目标的最佳方式(对此的任何提示也将不胜感激),但这是我目前必须处理的!

非常感谢任何帮助,尤其是示例!

谢谢你的时间!

而不是让一个 object (rows) 包含行 headers,另一个 object 包含所有行的所有单元格 (cellvalues ), 我建议您以某种方式将单元格数据放入单个行数据中,这样您的数据结构将如下所示:

rows = [
  { rowID: 100, cells: [
      { cellID: 101, value: 'data' },
      { cellID: 102, value: 'data' }
    ]
  },
  { rowID: 200, cells: [
      { cellID: 201, value: 'data' },
      { cellID: 202, value: 'data' }
    ]
  }
]

这样一来,您就可以每行传递 cellValues,这样每行就可以有不同的单元格。

<Row> 创建一个单独的组件,呈现:

return 
  <tr>
    {this.props.cells.map( cell => { 
        return <Cell key={cell.cellID} value={cell.value} />
    })}
  </tr>

并将主渲染中的 <tr> 位更改为:

<Row key={row.keyID} cells={row.cells}/>

最后:对键使用索引是个坏主意,如key={i}。使用唯一标识单元格/行的 内容 的键。

更新:典型的情况是单元格或行首先在 front-end 中创建,并且只有在发布到数据库后才能获得它们的数据库 ID。
仍然获得键的唯一 ID 的选项是:

  • 在反应中创建单元格或行后,以时间戳的形式为 cell/row 提供一个唯一 ID。从数据库取回响应后,将时间戳替换为官方数据库密钥。 (这是您进行乐观更新的时候:临时显示新行,直到数据库为您提供正式行)。
  • 不显示 row/cell,直到您从服务器获得带有官方 ID 的响应
  • 通过散列所有 cell/row 内容的内容创建一个唯一的密钥(如果您非常确定 cell/row 内容不太可能相同)

希望这对您有所帮助。

您需要将 row 传递给单元格渲染方法:

  {rows.map((row, index) => this.state.isEditing ?
       <RowForm formKey={index} key={index} editStop={this.editStop} handleSubmit={this.handleSubmit} /> :
       <tr key={index}>
         {(row.cellValues || []).map((value, index) => {
            return (
                <Cells key={index} value={value.contents} />
          )})
         }
         <td>
           <button className="btn btn-primary" onClick={this.handleEdit.bind(this, row)}><i className="fa fa-pencil"></i>Edit</button>
         </td>
       </tr>
  )} 

希望对您有所帮助!