Родительский компонент имеет это
value={this.onUpdate(index)}
и onUpdate работает со значением и индексом
в дочернем компоненте у меня есть поле ввода, которое имеет
onChange={this.handleText(index)}
и это вызывает метод, который хочет отправить реквизит обратно
this.props.value(sum);
И я думаю, что мне нужно сделать интерфейс для значения, но как?
EDIT:
Родитель:
import * as React from "react";
import styled from 'styled-components';
import ShoppingList from './ShoppingList';
const Container = styled.div`
position:absolute;
left:0;
bottom:0;
right:0;
display: flex;
flex-direction: row;
justify-content: space-between;
`;
interface Item {
id: number;
value: number;
}
interface TPState {
shoppingLists2: object[];
shoplistsums: Item[];
sum: number;
}
class TotalPrice extends React.Component<{}, TPState> {
constructor(props: {}) {
super(props);
this.state = {
shoppingLists2: [ShoppingList],
sum: 0,
shoplistsums: []
}
}
AddShoppingList = () => {
let shoppingLists2 = this.state.shoppingLists2.concat(ShoppingList);
console.log(shoppingLists2)
this.setState({
shoppingLists2,
})
}
onUpdate = index => (value) => {
console.log('index, value', index, value)
let item: Item = {
id: index,
value: value
}
let shoplistsums = [...this.state.shoplistsums];
var indexOfItem = shoplistsums.map(e => e.id).indexOf(item.id);
if (indexOfItem === -1) {
shoplistsums.push(item);
}
else {
shoplistsums[indexOfItem] = item;
}
let sum = shoplistsums.map(this.amount).reduce(this.sum);
this.setState({
shoplistsums,
sum
})
}
amount(item) {
return item.value;
}
sum(prev, next) {
return prev + next;
}
render() {
return (
<div>
{this.state.shoppingLists2.map((ShoppingList, index) => (
<ShoppingList
key={index}
value={this.onUpdate(index)}
/>
))}
<Container>
<label>Total:</label>
<label>{this.state.sum + ' €'}</label>
<button onClick={this.AddShoppingList}>Add Receipt</button>
</Container>
</div>
);
}
}
export default TotalPrice;
Дети
import * as React from "react";
import styled from 'styled-components';
const Container = styled.div`
display: flex;
flex-direction: row;
justify-content: space-between;
`;
export interface SLProps {
}
interface SLState {
smallList: number[];
sum: number;
}
export default class ShoppingList extends React.Component<SLProps, SLState> {
constructor(props: SLProps) {
super(props);
this.state = {
smallList: [0],
sum: 0
}
}
handleText = i => e => {
let smallList = [...this.state.smallList];
let x = e.target.value;
if (isNaN(parseFloat(x))) {
smallList[i] = 0;
}
else {
smallList[i] = parseFloat(x);
}
let sum = smallList.reduce(function(a, b) {
return a + b;
});
this.props.value(sum);
this.setState({
smallList,
sum
})
}
addExpense = e => {
e.preventDefault()
let smallList = this.state.smallList.concat([0])
this.setState({
smallList
})
}
render() {
return (
<div>
<Container>
<select>
<option value="food">Food</option>
<option value="houseware">Houseware</option>
<option value="entertainment">Entertainment</option>
</select>
<button onClick={this.addExpense}>Add expense</button>
</Container>
{this.state.smallList.map((question, index) => (
<Container key={index}>
<input
type="text"
/>
<input
type="number"
step="0.01"
onChange={this.handleText(index)}
value={question === 0 ? '' : question}
/>
</Container>
))}
<Container>
<label>Total:</label>
<label>{this.state.sum + ' €'}</label>
</Container>
</div>
)
}
}