2015-07-30 2 views
6

Так у меня есть большой компонент, который будет моя форма:React Форма контролируется Flux Store (Лучшая практика?)

<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> 

Ok, так что onChange пожары пропеллер firstAction, который на самом деле Flux действие, которое будет обновлять мой магазин и сделать форму для повторной визуализации. У меня есть две хорошие вещи здесь, когда пользователь отправляет форму, я могу проверить значение FirstComponent в своем магазине, а также контролировать все мое состояние из родительского компонента.

Однако, этот обратный вызов onChange будет вызывать действие каждый раз, когда пользователь набирает один символ (чтобы он мог производить много вызовов, поэтому повторно снимает) < - может это вызвать серьезные проблемы с производительностью?

Вместо этого я мог бы использовать refs, и когда пользователь нажмет кнопку отправки, получите this.refs.myFirstComponent.state ... и у меня тоже будет значение (это будет Uncontrolled Component?) Но это не похоже на рекомендацию сообщества.

Итак, мой вопрос в том, является ли первый подход, который я описал выше, хорошим способом? Как я могу его оптимизировать? Таким образом, повторная визуализация, которая должна влиять только на FirstComponent, не делает SecondComponent и т. Д. Повторно рендерингом? Есть shouldComponentUpdate единственный способ пойти сюда?


Edit 1:

При первом подходе я столкнулся с проблемой ... У меня есть тест e2e с помощью WebdriverIO добавив значение в текстовое поле: http://webdriver.io/api/action/setValue.html

Я не Не знаю почему, но если я пытаюсь добавить слово «Тестирование» во входные данные, webdriver добавит только последнюю букву. Эта проблема исчезла, если не использовать состояние/хранилище вообще. Тем не менее, если у меня есть состояние внутри моей 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 работает. Есть еще идеи?

ответ

3

Ваш первый подход (т. Е. onChange срабатывает действие потока, которое обновляет хранилище и делает вашу повторную визуализацию) кажется хорошим способом. Я использую его так, и я видел, как другие люди так его использовали.

Что касается вашего следующего комментария:

Однако это OnChange обратного вызова будет вызывать действие каждый раз, когда пользователь вводит один символ (поэтому он может производить много звонков поэтому повторно делает) < - это может вызывают серьезные проблемы с производительностью?

Да, я так считаю. Я однажды создал компонент, который содержит много других компонентов вместе с некоторыми полями ввода. Всякий раз, когда я вводил символ в поле ввода, весь компонент (с другими компонентами, который он включает, и поля ввода) получил повторную визуализацию, что вызвало проблему с производительностью. Было заметно, что я быстро набрал. Вы можете проверить его с помощью https://facebook.github.io/react/docs/perf.html.

В любом случае, как я обошел проблему, как вы упомянули, путем внедрения shouldComponentUpdate().

Небольшой совет, который я хотел бы упомянуть, является создание пользовательских <Input /> компонент, который обтекает <input /> и реализации shouldComponentUpdate() (т.е. this.props.value !== nextProps.value || this.props.checked !== nextProps.checked) Таким образом, если вы создаете компонент формы, например, с большим количеством полей ввода (с помощью custom <Input />), изменяется только поле ввода, которое изменяется.

Мне бы хотелось увидеть, как другие люди тоже подходят к этой проблеме.

+0

Check my Edit 1, используя подход к действию, я столкнулся с проблемой с моими испытаниями e2e ... –

+0

Почему это может вызвать проблемы с производительностью? Я думал, что виртуальная DOM React обрабатывает такие проверки внутри себя и только визуализирует, что изменилось. Это замечательная особенность React, когда дело доходит до производительности. Я ошибаюсь? – Alex

Смежные вопросы