Подтвердить что ты не робот

ReactJS: Почему передается исходное состояние компонента prop-анти-шаблон?

Я создал небольшую панель инструментов ReactJS с помощью SocketIO для живых обновлений. Несмотря на то, что у меня есть обновление панели мониторинга, мне кажется, что я не совсем уверен, правильно ли я сделал это.

Больше всего меня беспокоит реквизит в getInitialState как анти-шаблон. Я создал панель мониторинга, которая получает прямые обновления с сервера, не требуя взаимодействия с пользователем, не загружая страницу. Из того, что я прочитал, this.state должен содержать вещи, которые будут определять, должен ли компонент повторно отображаться, и this.props.... Я еще не знаю.

Однако, когда вы изначально звоните React.render(<MyComponent />, ...), вы можете передавать только реквизиты. В моем случае я получаю все данные с сервера, поэтому исходные реквизиты в любом случае оказываются в this.state. Итак, у всех моих компонентов есть что-то вроде этого:

getInitialState: function() {
    return {
        progress: this.props.progress,
        latest_update: this.props.latest_update,
        nearest_center: this.props.nearest_center
    }
}

Что, если я неправильно истолковал вышеупомянутое сообщение в блоге, является анти-шаблоном. Но я не вижу другого способа впрыскивать государство в Компонент, и я не понимаю, почему это анти-шаблон, если я не переместлю все мои реквизиты, чтобы добавить initial к ним. Во всяком случае, я чувствую, что это анти-шаблон, потому что теперь мне нужно отслеживать больше переменных, чем раньше (те, которые были добавлены с помощью initial и без них).

4b9b3361

Ответ 1

Отказ от ответственности. Когда я ответил на этот вопрос, я учился/пытался реализовать vanilla Flux, и я немного скептически относился к этому. Позже я перенаправил все на Redux. Итак, совет: просто зайдите с Redux или MobX. Скорее всего, вам даже не понадобится ответ на этот вопрос (за исключением науки).

Передача внутреннего состояния компоненту как prop является анти-шаблоном, потому что метод getInitialState вызывается только при первом рендеринге компонента. Никогда больше. Это означает, что, если вы повторно визуализируете этот компонент, передавая другое значение как prop, компонент не будет реагировать соответственно, потому что компонент будет сохранять состояние с первого раза, когда он был визуализирован. Он очень подвержен ошибкам.

И вот что вам следует делать:

Попробуйте сделать ваши компоненты как можно более безгражданными. Безстоящие компоненты легче тестировать, поскольку они выводят вывод на основе ввода. Просто так.

Но эй.. мои данные об изменении компонентов... Я не могу сделать их безстоящими

Да, вы можете, для большинства из них. Чтобы сделать это, выберите внешний компонент в качестве держателя состояния. Используя ваш пример, вы можете создать компонент Dashboard, содержащий данные, и компонент Widget, который полностью не имеет состояния. Dashboard отвечает за получение всех данных, а затем рендеринг нескольких Widgets, которые получают все, что им нужно, через props.

Но у моих виджетов есть определенное состояние. Пользователь может их настроить. Как сделать их безстоящими?

Ваш Widget может вывешивать события, которые при обработке приводят к изменению состояния, содержащегося в Dashboard, в результате чего каждый Widget должен быть повторно удален. Вы создаете "события" в своем Widget, имея props, которые получают функцию.

Итак, теперь панель управления сохраняет состояние, но как передать ему исходное состояние?

У вас есть два варианта. Наиболее рекомендуемым является то, что вы вызываете вызов Ajax в методе Dashboard getInitialState, чтобы получить исходное состояние с сервера. Вы также можете использовать Flux, что является более сложным способом управления данными. Flux - скорее образец, а не реализация. Вы можете использовать pure Flux с реализацией Facebook Dispatcher, но вы можете использовать сторонние реализации, такие как Redux, Alt или Fluxxor.

В качестве альтернативы вы можете передать это начальное состояние как prop в Dashboard, явно объявив, что это только начальное состояние.. например, initialData, например. Если вы выберете этот путь, вы не сможете передать ему другое начальное состояние, потому что оно будет "запоминать" состояние после первого рендера.

OBS

Вы не совсем правы в своих определениях.

Состояние используется для хранения изменяемых данных, то есть данных, которые будут меняться в течение жизненного цикла компонента. Изменения состояния должны выполняться с помощью метода setState и вызывать повторный рендеринг компонента.

Реквизиты используются для передачи возвращаемых данных компонентам. Они не должны меняться в течение жизненного цикла компонента. Компоненты, которые используют только реквизиты, являются апатридами.

Это является релевантным источником информации о том, как передать исходное состояние компонентам.