React Hooks
Хуки появились в реакте в феврале 2019 года начиная с версии 16.8 и быстро стали популярными.
Их преимущества:
- позволяют отказаться от классов, которые чуть сложнее в реализации и чуть медленнее в быстродействии
- в некоторых случаях позволяют сделать код проще
Их преимущества:
- позволяют отказаться от классов, которые чуть сложнее в реализации и чуть медленнее в быстродействии
- в некоторых случаях позволяют сделать код проще
- избавляемся от this, которое в некоторых случаях может работать с ошибкой (вместо пользователя Боб письмо получит Алиса, что недопустимо)
Хуки позволяют в функциональных компонентах хранить state, иметь доступ к жизненному циклу компонентов, использовать контекст.
Хуки позволяют в функциональных компонентах хранить state, иметь доступ к жизненному циклу компонентов, использовать контекст.
Если хуки использовать правильно, они существенно упрощают структуру приложения.
Чтобы использовать хуки, их нужно импортировать из пакета react
import React, { useState } from 'react';
Пример кода с хуками
import React, { useState } from "react";
import ReactDOM from "react-dom";
const HookSwitcher = () => {
const [color, setColor] = useState("gray");
const setRed = () => setColor("red");
const setBlack = () => setColor("black");
return (
<>
<div style={{ padding: "40px 10px", backgroundColor: color }} />
<button onClick={setRed}>Red</button>
<button onClick={setBlack}>Black</button>
</>
);
};
ReactDOM.render(<HookSwitcher />, document.getElementById("root"));
Хук useState
Хук useState заменил обычный state в классовом компонентеРассмотрим хук
const [ color, setColor ] = useState('#c0c0c0');
Он содержит
- переменную color
- функцию для изменения этой переменной setColor
- значение по умолчанию '#c0c0c0'
Чтобы изменить значение переменной color по клику, вызываем функцию
Чтобы изменить значение переменной color по клику, вызываем функцию
onClick={() => setColor('#ff6666')}
Если нужно изменить свойство fontSize на основе предыдущего, недостаточно просто вызвать функцию setFontSize с нужным значением
нужно прописать функцию, получающую предыдущее значение и меняющую его
Если в state можно было поменять только одно поле объекта, а остальные оставались неизменными, в useState объект переписываются полностью
const [ fontSize, setFontSize ] = useState(18);
onClick={() => setFontSize(fontSize => fontSize + 2)}
Если в state можно было поменять только одно поле объекта, а остальные оставались неизменными, в useState объект переписываются полностью
Т.е, если в useState был объект, и нам нужно в нём поменять только одно свойство, остальные придётся переписать, иначе они сотрутся
Но есть вариант использовать деструктуризацию
const [person, setPerson] = useState{firstName: 'Bob', lastName: 'Smith'}
setPerson(person => {...person, firstName: 'Alisa'})
Отличия useState от state
1. Стейт один, useState может быть много
2. В стейте можно менять отдельные свойства, в useState нужно записывать все свойства, в том числе и те, которые не изменились
1. Стейт один, useState может быть много
2. В стейте можно менять отдельные свойства, в useState нужно записывать все свойства, в том числе и те, которые не изменились
useContext
useContext заменил (Higher-Order Component, HOC) - компоненты высшего порядка
Возможность передачи контекста - ещё одно преимущество хуков, которые позволяют сократить количество кода
чтобы передать два значения контекста в HOC понадобилось бы создать пять компонентов:
обёртка => контекст => обёртка => контекст => компонент, который эти контексты использует
При помощи хуков передача контекста очень упрощается
import React, { useContext } from 'react';
const MyContext = React.createContext();
const App = () => {
return(
<MyContext.Provider value='Hello useContext' >
<Child />
</MyContext.Provider>
);
}
const Child = () => {
const value = useContext(MyContext);
return(
<p>{value}</p>
);
}
export default App;
Хук useEffect
Хук useEffect позволяет создавать "side effects" (побочные эффекты), например, извлечение данных, ручное изменение структуры DOM, использование таймеров. В нём можно делать подписки, отправлять запросы управлять анимацией
Он служит той же цели, что методы жизненного цикла componentDidMount, componentDidUpdate и componentWillUnmount
В качестве параметра в useEffect() передается функция, которая определяет "эффект", который затем применяется в приложении
Второй необязательный параметр указывает в каких случаях вызывать эффект
- если второй параметр не передаётся, функция выполняется после каждого рендеринга, в том числе при первом рендеринге приложения.
- если второй параметр пустой массив, функция выполняется только при первом рендеринге
- если второй параметр значение переменной, хук выполняется каждый раз при изменении этой переменной
import React, { useState, useEffect } from 'react';
const Counter = ({value}) => {
useEffect(() => {console.log('useEffect()')}, [value])
return(
<p>{value}</p>
)
}
const App = () => {
const [value, setValue] = useState(0);
const [visible, setVisible] = useState(true);
if(visible) {
return(
<div>
<button onClick={() => setValue(value => value + 1)}>+</button>
<button onClick={() => setVisible(false)}>hide</button>
<Counter value={value}/>
</div>
);
} else {
return(
<button onClick={() => setVisible(true)}>visible</button>
)
}
}
export default App;