【问题标题】:React - How can I get a re-render to happen in my table?React - 我怎样才能在我的表中重新渲染?
【发布时间】:2016-07-04 05:04:54
【问题描述】:

我有一个表格,它以商店中的数据开始,然后可以按行进行编辑。编辑完成后,单击一个按钮以保存新值并将它们显示在表中。但是,这不会发生在我身上。我已经坚持了一段时间,并尝试了各种方法,但都没有奏效。我认为这可能是状态的问题,但我不知道如何更改它以使其正常工作!

我目前的代码是:

表:

import React from 'react';
import TableWithDataHeader from './TableWithDataHeader.jsx';
import TableWithDataBody from './TableWithDataBody.jsx';
import TableWithDataRowForm from './TableWithDataRowForm.jsx';
import {updateRowHistory} from '../../actions/DALIActions';
import AppStore from '../../stores/AppStore';

export default class TableWithData extends React.Component {
    state = {rows: [], isEditing: false, input: null};

    componentDidMount() {
        let rows = this.state.rows;
        rows.push({id: AppStore.getRowId(), cells: AppStore.getCells().historycells});
        this.setState({rows});
        console.log(rows);
    }

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

    handleInputChange = (newCellValuesArray) => {
        let input = this.state.input;
        input = newCellValuesArray;
        this.setState({input});
    };

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

    handleSubmit = (access_token, row_id) => {
        let newCellValuesArray = this.state.input;
        updateRowHistory(access_token, row_id, newCellValuesArray);
        this.setState({isEditing: false});
    };

    render() {

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

        return (
            <div>
                <div className="row">
                    <table className="table table-striped">
                        <thead>
                            <TableWithDataHeader />
                        </thead>
                        <tbody>
                            {rows.map(row => this.state.isEditing ? 
                                <TableWithDataRowForm 
                                    key={row.id} 
                                    cells={row.cells} 
                                    editStop={this.editStop.bind(null, row.id)} 
                                    handleSubmit={this.handleSubmit} 
                                    handleInputChange={this.handleInputChange} 
                                /> 
                                : 
                                <TableWithDataBody 
                                    key={row.id} 
                                    cells={row.cells} 
                                    handleEdit={this.handleEdit.bind(null, row.id)} 
                                />
                            )}
                        </tbody>
                    </table>
                </div>
            </div>
        );
    }
}

数据表开头为:

import React from 'react';

export default class TableWithDataBody extends React.Component {
    state = {cells: this.props.cells};

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

    render() {

        let {cells} = this.state;

        return (
            <tr>
                {cells.map(cell => {
                    return <td key={cell.id} className="text-center">{cell.contents}</td>
                })}
                <td>
                    <button className="btn btn-primary" onClick={this.handleEdit}><i className="fa fa-pencil"></i>Edit</button>
                </td>
            </tr>
        );
    }
}

行内编辑表单:

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

export default class TableWithDataRowForm extends React.Component {
    state = {cells: this.props.cells, newCellValues: []};

    onChange = (e) => {
        let newCellValues = this.state.newCellValues;
        newCellValues[e.target.id] = e.target.value;
        this.setState({newCellValues});
        console.log(newCellValues);
        let newCellValuesArray = [];
        for (let key in newCellValues) {
            if (newCellValues.hasOwnProperty(key)) {
                newCellValuesArray.push({contents: newCellValues[key]});
            }
        }
        console.log(newCellValuesArray);
        this.props.handleInputChange(newCellValuesArray);
    };

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

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

        let access_token = AppStore.getToken();
        let row_id = AppStore.getRowId();

        this.props.handleSubmit(access_token, row_id);
    };

    render() {

        let {cells, newCellValues} = this.state;

        return (
            <tr>
                {cells.map(cell => {
                    return <td key={cell.id} className="text-center"><input type="text" className="form-control" id={cell.id} defaultValue={cell.contents} onChange={this.onChange} /></td>
                })}
                <td>
                    <button className="btn btn-default"><i className="fa fa-ban" onClick={this.editStop}></i>Cancel</button>
                    <button className="btn btn-success"><i className="fa fa-cloud" onClick={this.handleSubmit}></i>Save</button>
                </td>
            </tr>
        );
    }
}

非常感谢您提供示例帮助,如果代码现在有点混乱,请见谅!

感谢您的宝贵时间

【问题讨论】:

    标签: reactjs reactjs-flux


    【解决方案1】:

    我可能遗漏了一些东西,但我没有看到您在哪里编辑 rows 状态?更改处理程序只是更改了input,您并没有将输入向下传递到数据表。

    我唯一看到 rows 被设置是在 componentDidMount 中,这解释了为什么它被填充但没有改变。

    【讨论】:

    • 是的,我知道,但是如何使用单元格的新值更新行?最好使用 componentWillUpdate 之类的东西还是某种自定义函数?
    • 每次顶部组件上的行发生变化时,只需调用setState({ rows })。此外,您应该仅在您的顶级 TableWithData 组件上有状态。所有子组件都应该只有只读属性,并调用回调来改变父组件的状态。
    • 是的,我知道需要发生什么,但我不知道该怎么做!我想我已经因为盯着代码太久而弄糊涂了,而修复可能比我现在告诉自己的要容易得多!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-11-22
    • 1970-01-01
    • 2020-12-04
    • 2019-12-05
    • 2021-07-09
    相关资源
    最近更新 更多