Hooks
Его давно нет, интересно, начали ли вы его использовать в проекте❓ Если вы не разбираетесь в детской обуви, можете прочитать эту статью и сравнить три основыHooks
и традицииclass
Отличие и использование компонентов😙
Три основы, о которых мы говоримHooks
Да:
-
useState
Поддерживается внутри функциональных компонентовstate
-
useEffect
Вызов с побочными эффектами внутри функционального компонента аналогичен вызовуcomponentDidMount
,componentDidUpdate
похожие, но разные -
useContext
Мониторинг изменений обновлений провайдера
useState
useState
позволяет нам поддерживать в функциональных компонентахstate
, традиционный подход требует использования компонентов класса. Например🌰, нам нужно поле ввода.По мере изменения содержимого поля ввода,label
Содержимое, отображаемое меткой, также изменяется одновременно. Вот два разных способа письма:
не используйте useState:
import React from "react";
// 1
export class ClassTest extends React.Component {
// 2
state = {
username: this.props.initialState
}
// 3
changeUserName(val) {
this.setState({ username: val })
}
// 4
render() {
return (
<div>
<label style={{ display: 'block' }} htmlFor="username">username: {this.state.username}</label>
<input type="text" name="username" onChange={e => this.changeUserName(e.target.value)} />
</div>
)
}
}
- Нам нужно определить класс и начать
React.Component
Унаследовано - Также необходимо инициализировать
state
- Инициализировать изменения
state
Методы - Наконец используйте
render
возврат функцииJSX
✅Используйте состояние использования:
// 1
import React, { useState } from "react";
export function UseStateTest({ initialState }) {
// 2
let [username, changeUserName] = useState(initialState)
// 3
return (
<div>
<label style={{ display: 'block' }} htmlFor="username">username: {username}</label>
<input type="text" name="username" onChange={e => changeUserName(e.target.value)} />
</div>
)
}
В родительском компоненте используйте:
import React from "react";
// 引入组件
import { UseStateTest } from './components/UseStateTest'
// 4
const App = () => (
<div>
<UseStateTest initialState={'initial value'} />
</div>
)
export default App;
- нужно от
react
введен вuseState
это 📦 - использовать
useState
метод, который получает параметр инициализации, определяетstate
переменные и изменяющиесяstate
Методы - Используйте его непосредственно там, где вам это нужно
state
Этой переменной достаточно, добавив обработчик события, чтобы вызвать изменениеstate
Методы - Вызывается в родительском компоненте через
props
передачаinitialState
значение инициализации
использоватьuseState
метод замены оригиналаclass
Мало того, что улучшится производительность, вы увидите гораздо меньше кода и вам больше не нужно будет использоватьthis
, поэтому он может поддерживатьstate
Функциональные компоненты действительно приятны в использовании 😀
-
class classTest extends React.Components {}
🔜function UseStateTest(props) {}
Написание функционального компонента -
this.state.username
🔜username
использоватьstate
ненужныйthis
-
this.setState({ username: '' })
🔜changeUserName('')
Изменятьstate
нет необходимости писатьsetState
метод
Описание документации: https://zh-hans.reactjs.org/docs/hooks-state.html
useEffect
useEffect
Он предназначен для обработки побочных эффектов, таких как выборка данных, создание подписок, ручное изменение DOM и т. д. ты можешь представить, что этоcomponentDidMount
а такжеcomponentDidUpdate
а такжеcomponentWillUnmount
комбинация.
В качестве примера 🌰🌰 допустим, мы создаемdiv
теги, которые отправляются при каждом нажатииhttp
запрос и страницаtitle
Изменить на соответствующее значение:
import React from 'react'
// 1
import { useState, useEffect } from 'react'
export function UseEffectTest() {
let [msg, changeMsg] = useState('loading...')
// 2
async function getData(url) { // 获取 json 数据
return await fetch(url).then(d => d.json())
}
// 3
async function handleClick() { // 点击事件改变 state
let data = await getData('https://httpbin.org/uuid').then(d => d.uuid)
changeMsg(data)
}
// 4
useEffect(() => { // 副作用
document.title = msg
})
return (
<div onClick={() => handleClick()}>{msg}</div>
)
}
- Первый из
react
введен вuseEffect
😳 - Затем создайте выборку данных
getData
метод - Создайте обработчик событий
handleClick
- использовать
useEffect
Обработка побочных эффектов: изменение страницыtitle
Если вы используете традиционный метод написания компонентов класса:
import React from 'react'
// 1
export class ClassTest extends React.Component {
// 2
state = {
msg: 'loading...'
}
// 3
async getData(url) { // 获取 json 数据
return await fetch(url).then(d => d.json())
}
handleClick = async () => { // 点击事件改变 state
let data = await this.getData('https://httpbin.org/uuid').then(d => d.uuid)
this.setState({ msg: data })
}
// 4
componentDidMount() {
document.title = this.state.msg
}
componentDidUpdate() {
document.title = this.state.msg
}
// 5
render() {
return (
<div onClick={this.handleClick}>{this.state.msg}</div>
)
}
}
- Сначала создайте класс
ClassTest
- инициализация
state
- Определение методов получения данных и обработчиков событий
- существует
componentDidMount
а такжеcomponentDidUpdate
смена сценыdocument.title
- наконец прошло
render
рендеринг функции
Все заснули после написания всего этого 💤
Использование useEffect не только убирает некоторые ненужные вещи, но и объединяетcomponentDidMount
а такжеcomponentDidUpdate
метод, в котором код нужно написать только один раз. 😀
Этот хук будет срабатывать после первого рендеринга и каждого обновления, если вам нужно вручную изменить пользовательские правила срабатывания
См. документацию: https://zh-hans.reactjs.org/docs/hooks-effect.html#tip-optimizing-performance-by-skipping-effects.
Кроме того, на официальном сайте также приводится пример подписки на клиринг подписки:
использоватьuseEffect
непосредственныйreturn
Функция будет делать:
Возвращаемая функция является необязательной и может использоваться или не использоваться:
Документация: https://zh-hans.reactjs.org/docs/hooks-effect.html#recap
Допустим, мы используем useEffect для отмены привязки обработчиков событий:
useEffect(() => {
window.addEventListener('keydown', handleKeydown);
return () => {
window.removeEventListener('keydown', handleKeydown);
}
})
useContext
useContext
Самое большое изменение заключается в том, что вы можете использоватьConsumer
при упаковкеChildren
Теперь предположим, что мы сначала создаем контекст, в котором есть файл с именемusername
изstate
, и модификацияusername
МетодыhandleChangeUsername
создать контекст
Без состояния использования:
Не используйтеstate hooks
Код выглядит следующим образом:
import React, { createContext } from 'react'
// 1. 使用 createContext 创建上下文
export const UserContext = new createContext()
// 2. 创建 Provider
export class UserProvider extends React.Component {
handleChangeUsername = (val) => {
this.setState({ username: val })
}
state = {
username: '',
handleChangeUsername: this.handleChangeUsername
}
render() {
return (
<UserContext.Provider value={this.state}>
{this.props.children}
</UserContext.Provider>
)
}
}
// 3. 创建 Consumer
export const UserConsumer = UserContext.Consumer
Посмотрите, что мы сделали:
- Сначала мы используем
createContext
созданный контекст - Затем мы создаем
Provider
, который определяетhandleChangeUsername
Методы иusername
изstate
, и возвращает пакетthis.props.children
изProvider
- Наконец мы возвращаемся
UserContext.Consumer
Код более подробный, вы можете использовать вышеупомянутыйuseState
Упростите это:
✅ Используйте состояние использования:
использоватьstate hooks
:
import React, { createContext, useState } from 'react'
// 1. 使用 createContext 创建上下文
export const UserContext = new createContext()
// 2. 创建 Provider
export const UserProvider = props => {
let [username, handleChangeUsername] = useState('')
return (
<UserContext.Provider value={{username, handleChangeUsername}}>
{props.children}
</UserContext.Provider>
)
}
// 3. 创建 Consumer
export const UserConsumer = UserContext.Consumer
использоватьuseState
Создание контекста более лаконично.
использовать контекст
После определения контекста давайте рассмотрим использованиеuseContext
и не использоватьuseContext
В чем разница 🎁:
Без использования контекста:
import React from "react";
import { UserConsumer, UserProvider } from './UserContext'
const Pannel = () => (
<UserConsumer>
{/* 不使用 useContext 需要调用 Consumer 包裹 children */}
{({ username, handleChangeUsername }) => (
<div>
<div>user: {username}</div>
<input onChange={e => handleChangeUsername(e.target.value)} />
</div>
)}
</UserConsumer>
)
const Form = () => <Pannel></Pannel>
const App = () => (
<div>
<UserProvider>
<Form></Form>
</UserProvider>
</div>
)
export default App;
✅ Используйте useContext:
просто импортироватьUserContext
,использоватьuseContext
Метод может быть:
import React, { useContext } from "react"; // 1
import { UserProvider, UserContext } from './UserContext' // 2
const Pannel = () => {
const { username, handleChangeUsername } = useContext(UserContext) // 3
return (
<div>
<div>user: {username}</div>
<input onChange={e => handleChangeUsername(e.target.value)} />
</div>
)
}
const Form = () => <Pannel></Pannel>
// 4
const App = () => (
<div>
<UserProvider>
<Form></Form>
</UserProvider>
</div>
)
export default App;
Посмотрите, что было сделано:
- Представить первым
useContext
- затем импортировать
UserProvider
и контекстUserContext
- Затем вызовите его в компоненте, который необходимо использовать.
useContext
способ получитьstate
- Конечно, предполагается использовать его в родительском компоненте.
UserProvider
вложенный мастерchildren
так черезuseContext
а такжеuseState
Рефакторинг завершен, и кажется, что кода стало намного меньше 😄
выше, три основныхHooks
Введение закончено, и вот как можно приступить к работе.Функциональные компоненты иHooks
Это действительно здорово использовать вместе⛄
Ссылаться на:
- https://codeburst.io/quick-intro-to-react-hooks-6dd8ecb898ed
- https://reactjs.org/docs/hooks-reference.html