【问题标题】:React State Partly Lost反应状态部分丢失
【发布时间】:2018-05-22 13:20:13
【问题描述】:

我正在尝试开发一个可编辑的表格,用户可以在其中添加数据行,然后将它们发送到后端。

应用在 componentDidMount() 函数中获取当前数据。

数据在反应表上呈现。

用户使用添加按钮 addrow() 函数添加新行。

用户保存数据 - 将更新的数据发送到后端。这是发生错误的时间:

(ERROR) 在 saveDataMeasurements = (measurements) =>{} 函数中,接收到的数据打印在 console.log 上,具有要发送到后端的所需状态。但是,发送的数据与接收的数据不同。我不知道为什么。

代码如下:

import React from 'react';
import ReactTable from "react-table";
import 'react-table/react-table.css';
import update from 'react-addons-update';


class DataCollectionDetailB extends React.Component{
    constructor(props){
       super(props)
       this.state = {
          data: []              
      };
    this.renderEditable = this.renderEditable.bind(this);
}

renderEditable(cellInfo) {
    return (
      <div
        style={{ backgroundColor: "#fafafa" }}
        contentEditable
        suppressContentEditableWarning
        onBlur={e => {
          const data = [...this.state.data];
          data[cellInfo.index][cellInfo.column.id] = e.target.innerHTML;
          this.setState({ data });
        }}
        dangerouslySetInnerHTML={{
          __html: this.state.data[cellInfo.index][cellInfo.column.id]
        }}
      />
    );
}

addrow = () =>{
    var objToday = new Date(),
    weekday = new Array('Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday'),
    dayOfWeek = weekday[objToday.getDay()],
    domEnder = function() { var a = objToday; if (/1/.test(parseInt((a + "").charAt(0)))) return "th"; a = parseInt((a + "").charAt(1)); return 1 == a ? "st" : 2 == a ? "nd" : 3 == a ? "rd" : "th" }(),
    dayOfMonth = today + ( objToday.getDate() < 10) ? '0' + objToday.getDate() + domEnder : objToday.getDate() + domEnder,
    months = new Array('January', 'February', 'March', 'April', 'May', 'June', 'July', 'August', 'September', 'October', 'November', 'December'),
    curMonth = objToday.getMonth(),
    curYear = objToday.getFullYear(),
    curHour = objToday.getHours() > 12 ? objToday.getHours() - 12 : (objToday.getHours() < 10 ? "0" + objToday.getHours() : objToday.getHours()),
    curMinute = objToday.getMinutes() < 10 ? "0" + objToday.getMinutes() : objToday.getMinutes(),
    curSeconds = objToday.getSeconds() < 10 ? "0" + objToday.getSeconds() : objToday.getSeconds(),
    curMeridiem = objToday.getHours() > 12 ? "PM" : "AM";

    var today = curYear + "-" + (curMonth + 1) + "-" + dayOfMonth.slice(0,2)

    var newrow = new Array();
    newrow.id = 0;
    newrow.date = today;
    newrow.location_lat = 0;
    newrow.location_lon = 0;
    newrow.value = 0;       

    var updateData = update(this.state.data, {$push: [newrow]});

    this.setState({data:updateData});
}

saveDataMeasurements = (measurements) =>{
    //send measurements to back end
    console.log(measurements)   //the data here is ok   
    fetch('http://localhost:3000/measurementsinsert', {
    method: 'post',
    headers: {'Content-Type': 'application/json'},
    body: JSON.stringify({
        measurements: measurements   //this data is different and dont present the 2 rows added
        })
    })
    .then(response => response.json())
    .then(data =>{ 
        console.log(data)           
    })
    .catch(error => { console.log('measurements insertions have failed', error); });
}

componentDidMount(){
    //get current measurements for field gs data collection task id on back end
    fetch('http://localhost:3000/measurementsfortaskgs', {
    method: 'post',
    headers: {'Content-Type': 'application/json'},
    body: JSON.stringify({              
        fieldgstask: this.props.field_gs_data_collection_task_id.fieldgsdc_id
        })
    })
    .then(response => response.json())
    .then(data => {
        if (data.length > 0) {
            this.setState({data:data})
        }else {
            var newrow = new Array();
            newrow.id = 0;
            newrow.date = 0;
            newrow.location_lat = " ";
            newrow.location_lon = " ";
            newrow.value = " ";

            this.setState({data:newrow})
        }                       
    })
    .catch(error => { console.log('request failed', error); });
}

render() {
    console.log("PROPS", this.state)

    const { data } = this.state;
    const columns=[ 
                {
              Header: "Id Data Collection Task",
              accessor: "id"

            },
            {
              Header: "Date",
              accessor: "date",
              Cell: this.renderEditable
            },
            {
              Header: "Latitude",
              accessor: "location_lat",
              Cell: this.renderEditable
            },
            {
              Header: "Longitude",
              accessor: "location_lon",
              Cell: this.renderEditable
            },
            {
              Header: "Value",
              accessor: "value",
              Cell: this.renderEditable
            }
        ]

    return(
        <div>               
            <p>Input the measurements in the table bellow</p>
            <button type="button" id="add" onClick={this.addrow}> Add </button>
            <ReactTable
                data={data}
                columns={columns}
            />
            <button type="submit" onClick={() => { this.saveDataMeasurements(data) }}>Save</button>             
        </div>
    )}
}

export default DataCollectionDetailB; 

【问题讨论】:

    标签: reactjs react-table


    【解决方案1】:

    我无法使用 react-table 解决问题。我通过创建一个简单的 html 表来解决这个问题,该表获取 onChange 事件和其他所有事情的相同逻辑。它确实有效。

        import React from 'react'
    
        class Table extends React.Component {
          constructor(props) {
            super(props);
            this.state = {
              measurements: [],
            };
          }
    
          addrow = () =>{
            console.log("add row")
    
            var objToday = new Date(),
            weekday = new Array('Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday'),
            dayOfWeek = weekday[objToday.getDay()],
            domEnder = function() { var a = objToday; if (/1/.test(parseInt((a + "").charAt(0)))) return "th"; a = parseInt((a + "").charAt(1)); return 1 == a ? "st" : 2 == a ? "nd" : 3 == a ? "rd" : "th" }(),
            dayOfMonth = today + ( objToday.getDate() < 10) ? '0' + objToday.getDate() + domEnder : objToday.getDate() + domEnder,
            months = new Array('January', 'February', 'March', 'April', 'May', 'June', 'July', 'August', 'September', 'October', 'November', 'December'),
            curMonth = objToday.getMonth(),
            curYear = objToday.getFullYear(),
    
    
            var today = curYear + "-" + (curMonth + 1) + "-" + dayOfMonth.slice(0,2)
    
    
            const newrow = {
              id: 0, 
              date: today, 
              location_lat: '',
              location_lon: '',
              value: '',
              sensor_id: 1,
              field_gs_data_collection_task_id: this.props.field_gs_data_collection_task_id.fieldgsdc_id 
    
            }
    
            this.setState({measurements:[...this.state.measurements, newrow]});
    
          }
    
          saveDataMeasurements = () =>{
              //send measurements to back end
              console.log("state of data", this.state.measurements)     
              fetch('http://localhost:3000/measurementsinsert', {
              method: 'post',
                headers: {'Content-Type': 'application/json'},
                body: JSON.stringify({
                  measurements: this.state.measurements 
                  })
             })
              .then(response => response.json())
              .then(data =>{ 
                console.log(data)       
              })
              .catch(error => { console.log('measurements insertions have failed', error); });
          }
    
          componentDidMount(){
            //get current measurements for field gs data collection task id on back end
            fetch('http://localhost:3000/measurementsfortaskgs', {
              method: 'post',
                headers: {'Content-Type': 'application/json'},
                body: JSON.stringify({          
                  fieldgstask: this.props.field_gs_data_collection_task_id.fieldgsdc_id
                  })
              })
              .then(response => response.json())
              .then(data => {
                if (data.length > 0) {
                  this.setState({measurements:data})
                }else {
                  var newrow = [];         
                  this.setState({measurements:newrow})
                }               
              })
              .catch(error => { console.log('request failed', error); });
          }
    
          handleChange(index, dataType, value) {
            const newState = this.state.measurements.map((item, i) => {
              if (i === index) {
                return {...item, [dataType]: value};
              }
              return item;
            });
    
            this.setState({
               measurements: newState
            });
          }
    
          render() {
            //console.clear();
            console.log("props", this.props)
            console.log("measurements", this.state)
            console.log(JSON.stringify(this.state.measurements));
            return (
                <div>
                  <button type="button" id="add" onClick={this.addrow}> Add </button>
                  <table className="table table-bordered">
                      <thead>
                          <tr>
                              <th>Id</th>
                              <th>Date</th>
                              <th>Latitude</th>
                              <th>Longitude</th>
                              <th>Value</th>
                          </tr>
                      </thead>
                      <tbody>
                          {this.state.measurements.map((row, index) => {
                              return (
                                  <tr key={index}>
                                      <td>
                                        <input onChange={(e) => this.handleChange(index, 'id', e.target.value)} 
                                               type='number' 
                                               //className='form-control' 
                                               //step='1' min="1"
                                               value={this.state.measurements[index].id}/>
                                      </td>
                                      <td>
                                        <input onChange={(e) => this.handleChange(index, 'date', e.target.value)} 
                                               type='text' 
                                               className='date'
                                               value={this.state.measurements[index].date}/>
                                      </td>
                                      <td>
                                        <input onChange={(e) => this.handleChange(index, 'location_lat', e.target.value)} 
                                               type='text'
                                               className='form-control'  
                                               //placeholder='6.00'
                                               value={this.state.measurements[index].location_lat}/>
                                      </td>
                                       <td>
                                        <input onChange={(e) => this.handleChange(index, 'location_lon', e.target.value)} 
                                               type='text'
                                               className='form-control'  
                                       //placeholder='6.00'
                                               value={this.state.measurements[index].location_lon}/>
                                      </td>
                                      <td>
                                        <input onChange={(e) => this.handleChange(index, 'value', e.target.value)} 
                                               type='number'
                                               className='form-control'  
                                               //placeholder='6.00'
                                               value={this.state.measurements[index].value}/>
                                      </td>
                                  </tr>
                              );
                          })}
                      </tbody>
                  </table>
                  <button type="submit" onClick={this.saveDataMeasurements}>Save</button>
                </div>
            );
          }
        }
    
        export default Table;
    

    【讨论】:

      猜你喜欢
      • 2022-01-01
      • 2020-05-31
      • 2021-03-16
      • 2017-01-28
      • 2011-03-31
      • 1970-01-01
      • 1970-01-01
      • 2020-03-10
      • 1970-01-01
      相关资源
      最近更新 更多