Итак, у меня есть большой компонент, который будет моей формой:
<form>
<FirstComponent value={this.state.firstValue}/>
<SecondComponent value={this.state.secondValue}/>
{more components here}
<input type="submit" ... />
</form>
Этот компонент формы прослушивает хранилище, которое обновляет свои значения, используя firstAction
, secondAction
и т. д.
Примечание. Компонент обновляет свое состояние на основе функции store.getState(), которая возвращает {firstValue: something, secondValue: something, etc}
.
Итак, скажем, мой FirstComponent
является вводом:
<input type="text" value={this.props.value}
onChange={(e)=>this.props.firstAction(e.target.value)}
</input>
Итак, onChange
запускает свойство firstAction
, которое на самом деле является действием Flux, которое обновит мой магазин и заставит форму повторно отображаться. Здесь у меня есть две хорошие вещи: когда пользователь отправляет форму, я могу проверить значение FirstComponent в своем магазине, а также контролировать все свое состояние из родительского компонента.
Однако этот обратный вызов onChange
будет вызывать действие каждый раз, когда пользователь вводит один символ (поэтому он может производить много вызовов, следовательно, повторно отображать) ‹-- может ли это вызвать серьезные проблемы с производительностью?
Вместо этого я мог бы использовать refs, и когда пользователь нажмет кнопку отправки, получить this.refs.myFirstComponent.state
... и у меня тоже будет значение (это будет Неуправляемый компонент?) Но это не похоже на рекомендацию сообщества.
Итак, мой вопрос: является ли первый подход, который я описал выше, хорошим способом? Как я могу оптимизировать его? Таким образом, повторный рендеринг, который должен влиять только на FirstComponent, не приводит к повторному рендерингу SecondComponent и так далее? shouldComponentUpdate
единственный способ добраться сюда?
Редактировать 1:
При первом подходе у меня возникла проблема... У меня есть тест e2e с использованием WebdriverIO, добавляющий значение в текстовое поле: http://webdriver.io/api/action/setValue.html
Я не знаю почему, но если я попытаюсь добавить слово «Тестирование» во ввод, веб-драйвер добавит только последнюю букву. Эта проблема исчезнет, если вообще не использовать состояние/хранилище. Однако, если у меня есть состояние внутри моего FirstComponent
, что-то вроде:
<input type="text" value={this.state.value}
onChange={(e)=>this.setState({firstValue: e.target.value})}
onBlur={()=>this.props.callback(this.state.firstValue)}
</input>
В этом случае кажется, что компонент быстрее реагирует при наборе текста (отрисовывает только себя), а затем, когда пользователь удаляет фокус, он обновляет хранилище. Я должен сказать, что мне не нравится этот подход, потому что он не следует шаблону подъема вашего состояния (и я чувствую, что дублирую состояние), НО кажется, что он работает быстрее и важнее: мой тест e2e работает. Есть еще идеи?