从 Reduce 中获取总值的总和

Getting sum of total value from Reduce

我有 3 个标签可以在单击按钮时接收输入 然后我需要第三个输入值的总和 代码有点工作 但它不是获取第三个输入的总和,而是看起来像下面的图像,其中输入有点像字符串(不确定如何调用它)。 任何帮助表示赞赏 What Total looks like

这是我的完整代码

import React, { Component } from 'react'; 
import './Bootstrap/css/bootstrap.min.css';


class App extends Component { 
  constructor(){ 
    super(); 
 
    this.state = { 
      mahasiswa : [], 
      tgl : null,
      nama : null, 
      nilai : null,
      nilaiArray: []
    }   
  
  } 
 
  setValueState(event){ 
    var value = event.target.value
    this.setState({ 
      [event.target.name] : value
    }) 
    var nilaiArrayTmp = this.state.nilaiArray;
    nilaiArrayTmp.push(value?parseFloat(value).toFixed(2):0)
    this.setState({
      nilaiArray: nilaiArrayTmp
    })
  }

  addData(){ 
    var data_tmp = this.state.mahasiswa;     
    data_tmp.push({nim : this.state.tgl, nama : this.state.nama, nilai : this.state.nilai}); 
    this.setState({ 
      mahasiswa : data_tmp 
    }) 
    
    
    
  } 
  
   
  render() { 
    const total=(this.state.mahasiswa.reduce((total,{nilai}) =>  total = total + nilai , 0 ));

    return (       
        <div className="container"> 
            <h2><b>Daftar Pengeluaran</b></h2>
            <div className="form-container"> 
                <div className="form-group"> 
                    <label>Waktu:</label> 
                    <input type="text" name="tgl" value={this.state.tgl} onChange={this.setValueState.bind(this)} className="form-control" /> 
                </div> 
                <div className="form-group"> 
                    <label>Deskripsi:</label> 
                    <input type="text" name="nama" value={this.state.nama} onChange={this.setValueState.bind(this)} className="form-control" /> 
                </div> 
                <div className="form-group"> 
                    <label>Jumlah:</label> 
                    <input type="number" name="nilai" value={this.state.nilai} onChange={this.setValueState.bind(this)} className="form-control" /> 
                </div> 
                <br />
                <button onClick={this.addData.bind(this)} type="button" className="btn btn-primary">Tambah</button> 
            </div>
            <br /> 
            <table className="table"> 
                <thead>      
                    <tr>
                        <th>No.</th>
                        <th>Waktu</th>
                        <th>Deskripsi</th>
                        <th>Jumlah</th>
                    </tr> 
                </thead> 
                <tbody> 
                    {this.state.mahasiswa.map((mhs, index)=>( 
                    <tr key={index}> 
                        <td>{index+1}</td>
                        <td>{mhs.tgl}</td> 
                        <td>{mhs.nama}</td>
                        <td>{mhs.nilai}</td>
                    </tr> 
                    ))} 
                    <tr>
                        <td></td>
                        <td></td>
                        <td>Total:</td>
                        <td>{total}</td>

                    </tr>
                </tbody> 
            </table>
        </div> 
    ); 
    } 
  };
  
export default App;

Input 默认输入为 string 并将状态设置为 String。因此 0+string = string 并且你得到一个字符串。

它不是添加到 0,而是将 0 转换为 string 并将 concatenating 其余值转换为它。

您可以相应地使用 parseIntparseFloat 将其用作 Integer 并获得所需的结果。

const total=(this.state.mahasiswa.reduce((total,{nilai}) => total + parseInt(nilai) , 0 ));

parseFloat(value).toFixed(2) returns是字符串类型,不是数字类型

setValueState(event){ 
  var value = event.target.value
  this.setState({ 
    [event.target.name] : value
  }) 
  var nilaiArrayTmp = this.state.nilaiArray;
  nilaiArrayTmp.push(value?parseFloat(value).toFixed(2):0) // <-- converted back to string type!
  this.setState({
    nilaiArray: nilaiArrayTmp
  })
}

因此在数组 reduce 回调中,您正在执行字符串连接。要解决,请将值转换回数字时间以进行加法。不要改变正在 returned 的 total 值,只是 return 当前 total 值加上下一个 nilai 值。

const total = this.state.mahasiswa.reduce(
  (total, { nilai }) => total + Number(nilai),
  0
);

状态突变

setValueStateaddData 处理程序中,您正在改变状态对象,但直接推入数组。

setValueState(event) { 
  var value = event.target.value
  this.setState({ 
    [event.target.name] : value
  }) 
  var nilaiArrayTmp = this.state.nilaiArray; // <-- reference to state
  nilaiArrayTmp.push(value?parseFloat(value).toFixed(2):0) // <-- state mutation!!
  this.setState({
    nilaiArray: nilaiArrayTmp // <-- reference saved back into state
  })
}

addData(){ 
  var data_tmp = this.state.mahasiswa; // <-- reference to state
  data_tmp.push({ // <-- state mutation!!
    nim: this.state.tgl,
    nama: this.state.nama,
    nilai: this.state.nilai,
  }); 
  this.setState({ 
    mahasiswa: data_tmp // <-- reference saved back into state
  });
}

在这两种情况下,您都应该使用功能状态更新和 return 新数组引用。

setValueState(event) { 
  const { name, value } = event.target;
  
  this.setState(prevState => ({
    [name]: value,
    nilaiArray: [
      ...prevState.nilaiArray,
      value ? Number(value).toFixed(2) : 0,
    ],
  }))
}

addData(){ 
  this.setState({ 
    mahasiswa: [
      ...prevState.mahasiswa,
      {
        nim: prevState.tgl,
        nama: prevState.nama,
        nilai: prevState.nilai,
      }
    ], 
  });
}