Я новичок в Reactjs. Все, что я пытаюсь сделать, это следующее:
У меня три поля: ВХОД, ВЫХОД, ИТОГО.
TOTAL = EXIT - ENTRY
Пример:
ВХОД | ВЫХОД | Всего
1 | 2 | 1
2 | 4 | 2
3 | 6 | 3
5 | 10 | 5
Здесь ВХОД и ВЫХОД - это поля, динамически добавляемые при нажатии кнопки + Добавить. Мне удалось добавить поля динамически, но я не получаю значение ВСЕГО.
var entry;
var exit;
class Calculator extends React.Component {
state = {
values: [{id:0,exit:0,entry:0}],
total:[]
};
add() {
this.setState(prevState => prevState.values.push(null));
}
changeVal(val, index, key) {
if (key == 'exit'){
exit = val;
}else{
entry =val;
}
this.setState(prevState => (prevState.values[index] = {id:index, exit:val, entry: val}));
}
getTotal() {
let total = 0;
for (let i = 0; i < this.state.values.length; i++) {
if (this.state.values[i] !== null) {
total = this.state.values[i].exit - this.state.values[i].entry;
}
}
return total;
}
render() {
return (
<div>
{this.state.values.map((val, index, key) => (
<div key = {index}>
<input
onChange = {e => this.changeVal(e.target.value, index, 'exit')}
name = { `exit[${index}]` }
type = "number"
value = {val}
placeholder = "Enter a value"
/>
<input
onChange = {e => this.changeVal(e.target.value, index, 'entry')}
name = { `entry[${index}]` }
type = "number"
value = {val}
placeholder = "Enter a value"
/>
<input
name = { `total[${index}]` }
type = "number"
value = {this.state.total}
/>
</div>
))}
<button onClick = {this.add.bind(this)}> +Add</button>
</div>
);
}
}
ReactDOM.render(<Calculator /> , document.getElementById('calculator'));
Также скажите, пожалуйста, лучше ли динамически добавлять поля ввода. Спасибо



![Безумие обратных вызовов в javascript [JS]](https://i.imgur.com/WsjO6zJb.png)


Вы можете сделать что-то вроде этого:
var entry;
var exit;
class Calculator extends React.Component {
state = {
values: [{ id: 0, exit: 0, entry: 0 }],
total: []
};
add() {
let { values } = this.state;
values.push({ id: 0, exit: 0, entry: 0 });
this.setState({ values });
}
changeVal(val, index, key) {
let { values } = this.state;
values[index][key] = val;
this.setState({ values });
}
getTotal(data) {
return Number(data.exit) - Number(data.entry);
}
render() {
let { values, total } = this.state;
return (
<div>
{values.map((val, index, key) => {
return (
<div key = {index}>
<input
onChange = {e => this.changeVal(e.target.value, index, "exit")}
name = {`exit[${index}]`}
type = "number"
value = {val.exit}
placeholder = "Enter a value"
/>
<input
onChange = {e => this.changeVal(e.target.value, index, "entry")}
name = {`entry[${index}]`}
type = "number"
value = {val.entry}
placeholder = "Enter a value"
/>
<input
name = {`total[${index}]`}
type = "number"
value = {this.getTotal(val)}
/>
</div>
);
})}
<button onClick = {this.add.bind(this)}> +Add</button>
</div>
);
}
}Вот живой демонстрация
Надеюсь, поможет :)
Есть несколько мест, где ваш код плохо себя ведет.
<input
onChange = {e => this.changeVal(e.target.value, index, 'exit')}
name = { `exit[${index}]` }
type = "number"
value = {val.exit}
placeholder = "Enter a value"
/>
Вы присвоили объекту значение value, вместо этого вы должны предоставить свойство (val.exit).
При добавлении вам нужно протолкнуть объект в массив значений.
add() {
this.setState(prevState => prevState.values.push({id:this.state.values.length,exit:0,entry:0}));}
при изменении значений вам необходимо изменить значение для определенного свойства.
changeVal(val, index, key) {
if (key == 'exit'){
exit = val;
}else{
entry =val;
}
var changeVal = this.state.values[index] || {id:index, exit:0, entry: 0};
changeVal[key] = val;
this.setState(prevState => ( prevState.values[index] = changeVal));}
Итого нужно вызвать функцию getTotal.
<input
name = { `total[${index}]` }
type = "number"
value = {this.getTotal(index)}
/>
Вот живой демонстрация.