Я работаю над существующим кодом React, который кто-то написал, и сталкиваюсь с некоторыми проблемами с производительностью в нем. Рассмотрим следующий фрагмент кода:
//ComponentA.js
class ComponentA extends React.Component {
this.state = { someValue : 'dummy' }
// Other code
// We are using Babel, so class fields are OK
updateVal = e => this.setState({ someValue : e.target.value})
// fetchData makes an ajax call
fetchData = () => { fetch(this.state.someValue) }
render() {
return (
<ComponentB val={this.state.someValue}
updateVal={this.updateVal}
fetchData={this.fetchData}/>
)
}
//ComponentB.js
class ComponentB extends React.Component {
render() {
return (
// Other code
//Input is a component from a library
<Input onChange={(e) => { this.updateValue(e) } }
onBlur={this.props.fetchData} />
value={this.props.val}
)
}
}
Теперь проблема в том, что всякий раз, когда пользователь вводит Input
, значение печатается через несколько секунд. Это потому, что ComponentA на самом деле является довольно большим компонентом (я знаю, что это плохо, но я не хочу его реорганизовывать сейчас, потому что он огромен, и у нас не так много времени), и он перерисовывается каждый раз, когда пользователь вводит. Чтобы избежать этого, я могу сделать Input
неконтролируемым компонентом и обновить ComponentA
someValue
onBlur
. Другой способ - получить initialState
in ComponentB
, равный val
prop. И onChange
, this.setState
вызывается только для ComponentB
. Тогда onBlur
, я могу обновить ComponentA
this.state.someValue
.
Однако в обоих этих подходах принцип single source of truth
Реакта потерян. Так что будет лучшим решением в этом случае?
Здесь я также хотел бы спросить, что вредного в использовании неконтролируемого компонента здесь?