Я пытаюсь создать приложение для калькуляции чаевых с React Native, где пользователь вводит общую сумму в текстовое поле, и сумма чаевых будет отображаться пользователю, как показано ниже.
Как видите, сумма отключена, и причина, вероятно, в том, что я ввожу текст:
<Text>Total Amount: </Text>
<TextInput
style = {styles.textInputContainer}
onChangeText = {this.handleTotalAmount}
onSubmitEditing = {this.handleTotalAmount}
/>
Однако я нашел обходной путь, при котором, если я также использую onSubmitEditing, поле будет правильно обновляться, когда я нажму «Return». Мне это не очень нравится, потому что я чувствую, что взламываю это вместе, не зная, как это работает, и что я также чувствую, что есть лучшее решение для передачи значения обновления другому классу.
Вот другие фрагменты моего кода, если они помогают показать, как я структурировал свое приложение. У меня есть класс TotalAmount, у которого есть TextInput, который будет принимать totalAmount, и я хочу передать этот totalAmount в свой класс TipAmount15 для расчета суммы чаевых. Мне удалось собрать все в одном классе, но, поскольку я хочу добавить больше чаевых, я хотел разделить классы. Пожалуйста, дайте мне знать, есть ли лучший способ обновления или лучшее свойство TextInput, чем onChangeText или onSubmitEditing! Помощь очень ценится.
class TotalAmount extends Component {
constructor(props) {
super(props);
this.state = {
totalAmount: ''
}
}
handleTotalAmount = (totalAmountInput) => {
this.setState({
totalAmount: totalAmountInput
})
}
render() {
return (
<View>
<View style = {styles.totalAmountContainer}>
<Text>Total Amount: </Text>
<TextInput
style = {styles.textInputContainer}
onChangeText = {this.handleTotalAmount}
onSubmitEditing = {this.handleTotalAmount}
/>
</View>
<TipAmount15
percent = {15}
totalAmount = {this.state.totalAmount}/>
</View>
)
}
}
class TipAmount15 extends Component {
constructor(props) {
super(props);
this.state = {
percent: '',
totalAmount: '',
tipAmount15:'',
postTipAmount15:''
}
}
componentWillReceiveProps(props) {
var percent = this.props.percent;
var totalAmountInput = this.props.totalAmount;
this.setState({totalAmount: totalAmountInput})
//Calculate Tip Percentages
this.setState({tipAmount15: parseFloat(totalAmountInput*(percent/100)).toFixed(2)})
this.setState({postTipAmount15: parseFloat(totalAmountInput * (1+(percent/100))).toFixed(2)})
}
render() {
return (
<View style = {styles.tipCalculatorContainer}>
<Text>{this.props.percent}%</Text>
<Text>Tip Amount: {this.state.tipAmount15}</Text>
<Text>Total Amount: {this.state.postTipAmount15}</Text>
</View>
)
}
}



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


Пара мыслей:
1)
У вас должна быть возможность рефакторинга TipAmount до чего-то более простого, например (обратите внимание, что в конце этого примера нужно ввести convert)
const TipAmount15 = ({ percent, totalAmount }) => {
const tipAmount = parseFloat(totalAmount * (percent/100)).toFixed(2)
return (
<View style = {styles.tipCalculatorContainer}>
<Text>{this.props.percent}%</Text>
<Text>Tip Amount: {tipAmount}</Text>
<Text>Total Amount: {Number(totalAmount) + Number(tipAmount)}</Text>
</View>
)
}
потому что все, что мы делаем, - это пара вычислений для представления пользователю. Все, что мы отображаем, можно легко преобразовать из заданных свойств, поэтому этому компоненту нет реальной необходимости сохранять свое собственное состояние.
2)
Почему TextInput в компоненте TotalAmount должен обрабатывать и onChange, и submit, если они оба просто вызывают один и тот же обработчик? Я не думаю, что в этом случае вам нужны оба.
Проблема заключалась в том, что я неправильно использовал componentWillReceiveProps.
componentWillReceiveProps(newProps) {
if (newProps.totalAmount != this.props.totalAmount){
var percent = this.props.percent;
var totalAmountInput = newProps.totalAmount;
this.setState({totalAmount: totalAmountInput});
this.setState({tipAmount15: parseFloat(totalAmountInput*(percent/100)).toFixed(2)})
this.setState({postTipAmount15: parseFloat(totalAmountInput * (1+(percent/100))).toFixed(2)})
}
}
При проверке, было ли изменение, теперь оно правильно обновляется с текстовым полем onChangeText и решает мою проблему.
Однако, хотя это и решило мою первоначальную проблему, я до сих пор не знаю, есть ли лучший способ передать информацию.
1) Я обязательно рассмотрю эти предложения, спасибо! 2) У меня были оба из них, потому что я не был уверен, какой из них использовать, и надеялся, что кто-то может с этим помочь, но я смог разобраться самостоятельно.