В этом посте мы поговорим о новой функции, доступной в React 16.8.0, Hooks — новом способе управления состоянием вашего приложения. С помощью этой новой функции можно создавать компоненты чище, проще и с помощью функциональных компонентов, да, вы правильно поняли, больше не нужно использовать классы, и вы также может обрабатывать методы жизненного цикла.
Цель этого поста — узнать, как использовать Hooks в приложениях React Native. Сначала я покажу вам базовый пример в очень распространенном случае использования, таком как форма. Кроме того, я объясню, как вы можете создавать свои собственные хуки и как справляться с их побочными эффектами.
Если вам нужна дополнительная информация о хуках, вы можете посмотреть здесь. Также стоит посмотреть это видео Софи Алперт и Дэна Абрамова, где они более подробно и с большим контекстом объясняют React Hooks.
Предпосылки
Чтобы запустить примеры кода из этого поста, вам необходимо установить react-native 0.59 или более раннюю версию, потому что именно она представляет хуки в React. RN 0.59 все еще является RC-версией, поэтому, чтобы протестировать ее, вы можете сделать это следующим образом:
react-native init ReactNativeHooks –version react-native@next
Если вы хотите проверить сдачу в RN 0.59, это ваше место.
Первый компонент
Я думаю, что лучший способ объяснить крючки — это показать пример того, как они используются в простом случае использования, таком как форма, где вам нужно заполнить адрес электронной почты, имя, а затем отправить это (очень распространенный вариант использования, очевидно, что отправка не будет реальной)
const FormHook = () => { const [formState, setForm] = useState({ email: "", name: "" }); return ( <View style={styles.container}> <Text style={styles.count}>Name</Text> <TextInput style={{ height: 40, borderColor: "gray", borderWidth: 1, width: 200, padding: 7 }} onChangeText={name => setForm({ ...formState, name })} value={formState.name} /> <Text style={styles.count}>Email</Text> <TextInput style={{ height: 40, borderColor: "gray", borderWidth: 1, width: 200, padding: 7 }} onChangeText={email => setForm({ ...formState, email })} value={formState.email} /> <Button onPress={() => setForm({ email: "", name: "" })} title="Send" /> </View> ); }; export default FormHook;
В приведенном выше примере мы можем видеть простоту хуков, я создал форму в функциональном компоненте (больше никаких классов, ага!!!!) и добавил крючок вверху, один из первое правило хуков заключается в том, что вам нужно объявить их в верхней части ваших функций:
const [formState, setForm] = useState({email: ‘’, name: ‘’})
Когда вы вызываете useState, сначала вам нужно передать начальное состояние, а затем, благодаря деконструкции массива, вы получите:
- первый параметр: текущее состояние формы.
- второй: это функция для изменения вашего текущего состояния.
Как видно из примера, вам не нужно привязывать функцию setForm к этому или чему-то подобному, потому что он уже находится в той же области видимости.
Побочные эффекты
В React 16.8 также представлен хук под названием useEffect, созданный для обработки побочных эффектов в функциональных компонентах, он похож на componentDidMount или componentDidUpdate для классов.
Что такое побочные эффекты? Побочные эффекты — это все операции, выполняемые за пределами локальной среды, в которой они выполняются, например, сетевой запрос, доступ к базам данных и так далее.
Вот пример предыдущего фрагмента с useEffect:
import React, {useState, useEffect} from 'react' import { Platform, StyleSheet, Text, View, TouchableOpacity, TextInput, Button, NetInfo, } from 'react-native' type Props = {} const FormHook = () => { const [formState, setForm] = useState({email: '', name: '', isOnline: true}) const handleFirstConnectivityChange = connectionInfo => { setForm({…formState, isOnline: connectionInfo.type !== 'none'}) } useEffect(() => { NetInfo.addEventListener('connectionChange', handleFirstConnectivityChange) return () => { NetInfo.removeEventListener( 'connectionChange', handleFirstConnectivityChange ) } }) return ( <View style={styles.container}> <Text style={styles.count}>Name</Text> <TextInput style={{ height: 40, borderColor: 'gray', borderWidth: 1, width: 200, padding: 7, }} onChangeText={name => setForm({…formState, name})} value={formState.name} /> <Text style={styles.count}>Email</Text> <TextInput style={{ height: 40, borderColor: 'gray', borderWidth: 1, width: 200, padding: 7, }} onChangeText={email => setForm({…formState, email})} value={formState.email} /> <Button disabled={!formState.isOnline} onPress={() => setForm({…formState, email: '', name: ''})} title="Send" /> </View> ) } export default FormHook
В приведенном выше примере мы используем хук useEffect для подписки на изменения сетевой информации с помощью NetInfo, также, как вы можете видеть, он обрабатывается, когда этот компонент размонтирован и нам нужно почистить слушателя, все это делается здесь:
useEffect(() => { NetInfo.addEventListener("connectionChange", handleFirstConnectivityChange); return () => { NetInfo.removeEventListener( "connectionChange", handleFirstConnectivityChange ); }; });
Разве это не намного чище? вы можете обрабатывать побочные эффекты внутри вашего функционального компонента без необходимости связывать функции с классами.
Пользовательские крючки
Что, если то, что мы действительно хотим, это повторное использование хуков, которые мы ранее создали, чтобы мы не повторяли наш код в каждом компоненте, да, это возможно, в следующем примере вы увидите, как я создал хук в React Native для иметь возможность проверить, находится ли ваше устройство в сети или нет:
import React, { useState, useEffect } from "react"; import { NetInfo } from "react-native"; export default () => { const [isOnline, setIsOnline] = useState(null); handleFirstConnectivityChange = connectionInfo => { setIsOnline(connectionInfo.type !== "none"); }; useEffect(() => { NetInfo.addEventListener("connectionChange", handleFirstConnectivityChange); return () => { NetInfo.removeEventListener( "connectionChange", handleFirstConnectivityChange ); }; }); return isOnline; };
Вы можете получить доступ к этому коду здесь.
Первоначально опубликовано на www.react-native-learner.com 15 февраля 2019 г.