Где хранить данные компонента React: состояние, хранилище, статическое и это

С появлением React и Redux возник общий вопрос:

Что я должен хранить в хранилище Redux, а что - в локальном состоянии?

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

Давайте рассмотрим, что каждый из них, и когда вы должны их использовать.

Местное государство

Когда React был впервые представлен, нам было представлено локальное состояние. О локальном состоянии важно знать, что при изменении значения состояния запускается повторная отрисовка.

Это состояние может быть передано потомкам как свойства, что позволяет вам разделять ваши компоненты между интеллектуальными компонентами данных и немыми презентационными компонентами, если вы выберете.

Вот базовое приложение счетчика, использующее локальное состояние:

Ваши данные (значение счетчика) хранятся в компоненте App и могут передаваться его дочерним элементам.

Случаи применения

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

В настоящее время рекомендуется использовать локальное состояние для обработки состояния вашего пользовательского интерфейса (UI), а не данных. Например, использование управляемого компонента для заполнения формы является вполне допустимым использованием локального состояния.

Другим примером данных пользовательского интерфейса, которые можно сохранить в локальном состоянии, может быть текущая вкладка из списка параметров.

Хороший способ подумать, когда использовать локальное состояние, - это подумать, будет ли сохраненное вами значение использоваться другим компонентом. Если значение относится только к одному компоненту (или, возможно, к одному дочернему элементу этого компонента), то можно безопасно сохранить это значение в локальном состоянии.

Вывод: сохраняйте состояние пользовательского интерфейса и временные данные (например, входные данные формы) в локальном состоянии.

Redux магазин

Потом, по прошествии некоторого времени, и все начали привыкать к идее однонаправленного потока данных, мы получили Redux.

С Redux мы получаем глобальный магазин. Этот магазин находится на самом высоком уровне вашего приложения и передает данные всем детям. Вы подключаетесь к глобальному хранилищу с помощью оболочки подключения и функции mapStateToProps.

Сначала люди складывают все в магазин Redux. Пользователи, модальные окна, формы, сокеты… вы называете это.

Ниже показано то же приложение счетчика, но с использованием Redux. Важно отметить, что counter теперь поступает из this.props.counter после сопоставления с mapStateToProps в connect , которая берет значение счетчика из глобального хранилища и сопоставляет его с реквизитами текущего компонента.

Теперь, когда вы нажимаете кнопку, отправляется действие и обновляется глобальное хранилище. Данные обрабатываются вне нашего локального компонента и передаются вниз.

Стоит отметить, что при обновлении свойств также запускается повторная отрисовка - точно так же, как при обновлении состояния.

Случаи применения

Хранилище Redux отлично подходит для хранения состояния приложения, а не состояния пользовательского интерфейса. Прекрасный пример - статус входа пользователя. Многим из ваших компонентов потребуется доступ к этой информации, и как только статус входа в систему изменится, все эти компоненты (по крайней мере, те, которые отображаются) необходимо будет повторно отобразить с обновленной информацией.

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

Вывод: храните данные, которыми вы собираетесь делиться между компонентами, в магазине.

это. ‹something›

this - одна из наименее используемых функций при работе с React. Люди часто забывают, что React - это просто JavaScript с синтаксисом ES2015. Все, что вы можете делать в JavaScript, вы можете делать и в React.

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

Мы сохраняем значение счетчика в компоненте и используем forceUpdate () для повторного рендеринга при изменении значения. Это связано с тем, что изменение чего-либо, кроме состояния и свойств, не приводит к повторной отрисовке.

На самом деле это пример того, как вы должны не использовать this. Если вы обнаружите, что используете forceUpdate (), вероятно, вы что-то делаете неправильно. Для значений, изменение которых должно вызывать повторную визуализацию, следует использовать локальное состояние или props / хранилище Redux.

Случаи применения

Вариант использования this - хранить значения, изменение которых не должно вызывать повторную визуализацию. Например, сокеты - идеальное место для хранения на this.

Кроме того, многие люди не осознают, что они уже постоянно используют this в определениях своих функций. Когда вы определяете render (), вы действительно определяете this.prototype.render = function (), но это скрыто за синтаксисом класса ES2015.

Вывод: используйте this для хранения вещей, которые не должны вызывать повторную визуализацию.

Статический

Статические методы и свойства - это, пожалуй, наименее известный аспект классов ES2015 (успокойтесь, да, я знаю, что они на самом деле не классы под капотом), в основном потому, что они используются не так часто. Но на самом деле они не особо сложные. Если вы использовали PropTypes, значит, вы уже определили статическое свойство.

Следующие два блока кода идентичны. Первый - это то, как большинство людей определяют PropTypes. Во-вторых, как их можно определить с помощью static.

Как видите, static не так уж и сложен. Это просто еще один способ присвоить значение классу. Основное различие между static и this заключается в том, что вам не нужно создавать экземпляр класса для доступа к значению.

В приведенном выше примере вы можете видеть, что для получения значения staticProperty мы могли бы просто вызвать его прямо из класса, не создавая его экземпляра, но чтобы получить prototypeProperty, нам пришлось создайте его с помощью new App ().

Случаи применения

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

PropTypes - это пример служебной функции, которую вы можете присоединить к чему-то вроде компонента Button, поскольку для каждой отображаемой кнопки потребуются те же значения.

Другой вариант использования - если вас беспокоит избыточное получение данных. Если вы используете GraphQL или Falcor, вы можете указать, какие данные вы хотите вернуть со своего сервера. Таким образом, вы не получите намного больше данных, чем вам действительно нужно для вашего компонента.

Таким образом, в примере компонента выше, прежде чем запрашивать данные для определенного компонента, вы можете быстро получить массив требуемых значений для вашего запроса с помощью App.requiredData. Это позволяет вам сделать запрос без чрезмерного получение.

Вывод: вероятно, вы никогда не будете использовать статический.

Другой вариант…

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

Есть определенные ситуации, в которых это имеет смысл, но по большей части вам просто не следует этого делать.

Вы можете видеть, что это почти то же самое, что и использование this, за исключением того, что мы сохраняем значение вне нашего компонента, что может вызвать проблемы, если у вас есть более одного компонента на файл. Вы можете использовать это для установки значений по умолчанию, если значения не привязаны к вашему магазину, в противном случае было бы лучше использовать статический для свойств по умолчанию.

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

Вывод: не используйте переменные в области видимости модуля, если вы не знаете, что делаете.