React - 需要一些帮助来将数据保存到 table

React - require some aid with saving data to a table

我有一个 table 具有动态生成的列 headers 和行,用户可以在行中输入数据,当他们单击“保存”时,数据应保存到该行中,但在此刻它没有将值保存到 table 但它正在将它们保存在我的数据库中。理想情况下,我希望这样,当单击保存按钮时,数据将保存到该行,然后可以在该行中查看(如果这有意义的话)。

这是我正在使用的代码(我知道它现在一团糟!):

数据输入表单代码:

import React from 'react';
import AppStore from '../../stores/AppStore';

export default class RowForm extends React.Component {
    state = {dataEntries: []};

    onChange = (event, element) => {
        let dataEntries = this.state.dataEntries;
        dataEntries[element] = event.target.value;
        this.setState({dataEntries});
    };

    editStop = () => {
        this.props.editStop();
    };

    handleSubmit = (e) => {
        e.preventDefault();

        let access_token = AppStore.getToken();
        let id = AppStore.getTable().id;
        let dataEntries = this.state.dataEntries;
        let dataEntriesArray = [];
        for (let key in dataEntries) {
            if (dataEntries.hasOwnProperty(key)) {
                dataEntriesArray.push({contents: dataEntries[key]});
            }
        }

        this.props.handleSubmit(access_token, id, dataEntriesArray);

    };

    componentDidMount() {
        let nameArray = AppStore.getTable().columns.map((obj) => {
            return obj.name;
        });

        let dataEntries = nameArray.reduce((obj, name) => {
            obj[name] = null;
            return obj;
        }, {});
        this.setState({dataEntries});
    }

    render() {

        let {dataEntries} = this.state;

        return (
            <tr>
                {Object.keys(dataEntries).map((element) => {
                    return (
                        <td key={element}><input type="text" className="form-control" id={element} placeholder="enter data" value={dataEntries[element]} onChange={event => this.onChange(event, element)} /></td>
                    );
                })}
                <td>
                    <button className="btn btn-default" onClick={this.editStop}><i className="fa fa-ban"></i>Cancel</button>
                    <button className="btn btn-success" onClick={this.handleSubmit}><i className="fa fa-check"></i>Save</button>
                </td>
            </tr>
        );
    }

数据输入并提交后(是一个objects的数组,如dataEntriesArray = [{contents: "value"}, {contents: "value"}, {contents : "value"}, {内容: "value"}].

这是我渲染 table 的方式(我认为这就是问题所在):

import React from 'react';
import TableHeader from './TableHeader.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: [], isNew: false, isEditing: false};

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

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

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

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

    render() {

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

        let headerArray = AppStore.getTable().columns;

        return (
            <div>
                <div className="row" id="table-row">
                    <table className="table table-striped">
                        <thead>
                            <TableHeader />
                        </thead>
                        <tbody>
                            {rows.map((row, index) => this.state.isEditing ?
                                <RowForm formKey={index} key={index} editStop={this.editStop} handleSubmit={this.handleSubmit} /> :
                                <tr key={index}>
                                    {headerArray.map((element, index) => {
                                        return (
                                            <td key={index} id={element.id}></td>
                                        );
                                    })}
                                    <td>
                                        <button className="btn btn-primary" onClick={this.handleEdit.bind(this, row)}><i className="fa fa-pencil"></i>Edit</button>
                                    </td>
                                </tr>)}
                        </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>
        );
    }
}

我目前正在使用 flux,并且理想情况下希望暂时继续使用它(我知道 redux,但理想情况下我希望在开始重构我的代码之前让它在 flux 中工作)。我怀疑我渲染 table.

的方式有问题

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

谢谢你的时间!

看起来您可能想将 table 数据提取到您的商店中,您的 UI 子元素触发更改事件,然后您的商店更新其数据并触发更改事件,您的父组件可以监听和更新。

类似于下面的简化示例,它改变了数组元素:

class Store extends EventEmitter {
  constructor() {
    super()

    this.data = [ 'a', 'b', 'c' ]
  }

  onChange() {
    this.emit( 'update', this.data )
  }

  mutate( index, value ) {
    this.data[ index ] = value
    this.onChange()
  }
}

var store = new Store()

class ChildComponent extends React.Component {
  constructor( props ) {
    super( props )
  }

  // You probably want to use a dispatcher rather than directly accessing the store
  onClick = event => {
    store.mutate( this.props.index, this.props.value + 'Z' )
  }

  render() {
    return <button onClick={ this.onClick }>{ this.props.value }</button>
  }
}

class ParentComponent extends React.Component {
  constructor( props ) {
    super( props )

    // You probably want to be smarter about initially populating state
    this.state = {
      data: store.data
    }
  }

  componentWillMount() {
    store.on( 'update', data => this.setState({ data: data }) )
  }

  render() {
    let cells = this.state.data.map( ( value, index ) => <ChildComponent index={ index } value={ value } /> )

    return (
      <div>
        { cells }
      </div>
    )
  }
}

为简洁起见,这里的子组件直接告诉商店更改值,您可能希望分派 messages/actions 并让商店决定如何响应,关键是将商店数据传递给更新其状态并触发重新渲染的父组件。

这里的流程本质上是 UI 是愚蠢的,它只是呈现它从商店收集的数据,并在用户操作时发送一条消息告诉商店 update/mutate检测到(在这种情况下按下按钮,但听起来您需要某种输入),当商店中的数据发生变化时,它会发出(或者也可以使用调度程序)一个更改事件,该事件强制 UI 重新呈现新状态。由于在此阶段重新呈现子组件,它们会填充新的数据状态,确保您的 UI 保持一致。