React - 需要一些帮助,将数据保存到表中

时间:2016-03-03 11:09:07

标签: reactjs reactjs-flux

我有一个包含动态生成的列标题和行的表,用户可以在行中输入数据,当他们点击保存时,数据应保存到该行中,但目前它不保存值到表,但它将它们保存在我的数据库中。理想情况下,我希望它能够在单击保存按钮时将数据保存到行中,然后在该行中查看(如果有意义的话)。

以下是我正在使用的代码(我知道目前这是一团糟!):

数据输入表格代码:

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>
        );
    }

输入并提交数据后(它是一个对象数组,如dataEntriesArray = [{contents:&#34; value&#34;},{contents:&#34; value&#34;},{contents :&#34;价值&#34;},{内容:&#34;价值&#34;}]。

以下是我如何呈现表格(这是我认为的问题所在):

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但是我希望在开始重构我的代码之前让它在变化中工作)。我怀疑这是我渲染表格的问题。

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

谢谢你的时间!

1 个答案:

答案 0 :(得分:1)

您可能希望将表数据提取到商店中,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>
    )
  }
}

为简洁起见,这里的子组件直接告诉商店更改值,您可能想要调度消息/操作并让商店决定如何响应,关键是商店数据传递给父组件,它会更新其状态并触发重新渲染。

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