编写一个名为Member
的组件,我正在进行一些计算,我将它存储在this.state
中,然后再将其发送到其他地方,但是在解雇一个onChange
处理程序时遇到了问题某些状态值为undefined
,但应填充一些值。
组件Member
import React from "react";
import {calcSCR, difference, multiply} from "../../utils/Calculations";
import {SCR_COEFF} from "../../constants/calc";
class Member extends React.Component {
constructor(props){
super(props);
this.state = {
id: "1",
full_name: 'Mocked member 1',
role: 'Developer',
salary: 1650,
hourly_cost: 19.6, // SCR = (gross * coeff) / 100
project_data: {
project_id: '1',
hourly_rate: 40,
occupation: 50,
estimate_hours: 70,
revenue: 2800,// revenue = estimate_hours * hourly_rate
cost: 1372,// cost = estimate_hours * hourly_cost
profit: 1428// profit = revenue - cost
}
};
this.onSalaryChange = this.onSalaryChange.bind(this);
this.onHourlyCostChange = this.onHourlyCostChange.bind(this);
this.onHourlyRateChange = this.onHourlyRateChange.bind(this);
this.onEstimateHoursChange = this.onEstimateHoursChange.bind(this);
this.onRevenueChange = this.onRevenueChange.bind(this);
this.onCostChange = this.onCostChange.bind(this);
this.onNameChange = this.onNameChange.bind(this);
this.onOccupationChange = this.onOccupationChange.bind(this);
this.save = this.save.bind(this);
}
save(){
}
onNameChange(e){
this.setState({
full_name: e.target.value
})
}
onSalaryChange(e){
let salary = e.target.value;
this.setState({
salary: salary,
hourly_cost: calcSCR(salary, SCR_COEFF)
})
}
onHourlyRateChange(e){
let hourly_rate = e.target.value;
let estimate_hours = this.state.project_data.estimate_hours;
this.setState({
project_data: {
hourly_rate: hourly_rate,
revenue: multiply(estimate_hours, hourly_rate)
}
})
}
onOccupationChange(e){
this.setState({
project_data: {
occupation: e.target.value
}
})
}
onEstimateHoursChange(e){
let estimate_hours = e.target.value;
this.setState({
project_data: {
estimate_hours: estimate_hours,
revenue: multiply(estimate_hours, this.state.project_data.hourly_rate),
cost: multiply(estimate_hours,this.state.hourly_cost)
}
})
}
onHourlyCostChange(e){
let hourly_cost = e.target.value;
this.setState({
hourly_cost: hourly_cost,
project_data: {
cost: multiply(this.state.project_data.estimate_hours, hourly_cost)
}
})
}
onRevenueChange(e){
let revenue = e.target.value;
this.setState({
project_data: {
revenue: revenue,
profit: difference(revenue,this.state.project_data.cost)
}
})
}
onCostChange(e){
let cost = e.target.value;
this.setState({
project_data: {
cost: cost,
profit: difference(this.state.project_data.revenue,cost)
}
})
}
render(){
let {projectName} = this.props;
let data = this.state;
return (
<div className="member">
<a className="member__short_info" role="button" data-toggle="collapse" href={`#${data.id}`} aria-expanded="false" aria-controls={data.id}>
{data.full_name}
</a>
<div className="collapse member__member_full_info" id={data.id}>
<div className="member__full_info__row">
<div className="row">
<div className="col-sm-12 col-md-12 com-lg-12 member__full_info__header">
{projectName}
</div>
<div className="col-sm-12 col-md-12 col-lg-6 member__full_info__column">
<label htmlFor="full_name" className="member__full_info__label">Member full name:</label>
<input id="full_name" type="text" name="full_name" value={data.full_name} onChange={this.onNameChange}/>
</div>
<div className="col-sm-12 col-md-12 col-lg-6 member__full_info__column">
<label htmlFor="salary" className="member__full_info__label">Salary:</label>
<input id="salary" type="text" name="salary" value={data.salary} onChange={this.onSalaryChange}/>
</div>
<div className="col-sm-12 col-md-12 col-lg-6 member__full_info__column">
<label className="member__full_info__label">Hourly cost: </label>
<input id="hourly_cost" type="text" name="hourly_cost" value={data.hourly_cost} onChange={this.onHourlyCostChange}/>
</div>
<div className="col-sm-12 col-md-12 col-lg-6 member__full_info__column">
<label htmlFor="hourly_rate" className="member__full_info__label">Hourly rate</label>
<input id="hourly_rate" type="text" name="hourly_rate" value={data.project_data.hourly_rate} onChange={this.onHourlyRateChange}/>
</div>
<div className="col-sm-12 col-md-12 col-lg-6 member__full_info__column">
<label htmlFor="occupation" className="member__full_info__label">Occupation in project (%): </label>
<input id="occupation" type="text" name="occupation" value={data.project_data.occupation} onChange={this.onOccupationChange}/>
</div>
<div className="col-sm-12 col-md-12 col-lg-6 member__full_info__column">
<label htmlFor="estimate_hours" className="member__full_info__label">Estimate hours: </label>
<input id="estimate_hours" type="text" name="estimate_hours" value={data.project_data.estimate_hours} onChange={this.onEstimateHoursChange}/>
</div>
<div className="col-sm-12 col-md-12 col-lg-4 member__full_info__column">
<label className="member__full_info__label">Revenue: {data.project_data.revenue}</label>
{/*<input id="revenue" type="number" name="revenue" value={data.project_data.revenue} onChange={this.onRevenueChange}/>*/}
</div>
<div className="col-sm-12 col-md-12 col-lg-4 member__full_info__column">
<label className="member__full_info__label">Cost: {data.project_data.cost}</label>
{/*<input id="cost" type="number" name="cost" value={data.project_data.cost} onChange={this.onCostChange}/>*/}
</div>
<div className="col-sm-12 col-md-12 col-lg-4 member__full_info__column">
<label className="member__full_info__label">Profit: {data.project_data.profit}</label>
</div>
<div className="col-sm-12 member__full_info__save">
<button className="modal-component positive-btn no-margin" onClick={this.save}>Save</button>
</div>
</div>
</div>
</div>
</div>
);
}
}
export default Member;
例如:内部onHourlyRateChange
函数estimate_hours
在更改后变为undefined
。
内部onEstimateHoursChange
状态变量this.state.project_data.hourly_rate
和this.state.project_data.hourly_cost
也变为undefined
。我不知道为什么会这样。也许你可以给我一些建议吗?
答案 0 :(得分:1)
看起来所有嵌套状态都遇到问题,即嵌套在project_data中。组件只是一次更新子元素,即在第一次按键时和所有后续按键时,它没有更新任何内容,而是嵌套状态项的值未定义,这是非常奇怪的。解决此问题的方法就像您可以将所有嵌套状态项移动为单级状态项。 例如:
this.state = {
project_data: { hourly_rate: 40 }
}
相反,您可以将子项目移动到父项
this.state = {
project_data_hourly_rate: 40
}
答案 1 :(得分:1)
您可以部分更新状态对象的顶级属性,但嵌套更新将不起作用。
immutability-helper的update
(替换为react-addons-update)可用于更新嵌套属性:
import update from 'immutability-helper';
const newData = update(myData, {
x: {y: {z: {$set: 7}}},
a: {b: {$push: [9]}}
});