Автор оригинала: FreeCodeCamp Community Member.
Анимации наслаждаются пользователями. И вы бы подумали, что по чистому объему статей, которые реагируют крюки, восхищающие разработчики. Но для меня усталость начинала ползать мне мнения на крючках.
Но Serendipity спас меня. Я нашел пример, который был хорошим совпадением для реактивных крюков, а не только «нового способа». Как вы, возможно, догадались на название этой статьи, этот пример был анимацией.
Я работал над приложением реагирования с картами в сетке. Когда предмет был удален, я хотел оживить свой выход, как это.
К сожалению, есть нюансы, чтобы сделать эту работу. И мое решение привело меня к хорошему использованию реактивных крюков.
Что мы будем делать?
- Начните с приложения базового примера
- постепенно анимировать исчезает элементов, подчеркивая некоторые проблемы
- Как только мы достигнем желаемой анимации, мы ревертеруемся многоразовой анимационный компонент
- Мы будем использовать этот компонент для анимирования боковой панели и навбар
- а также …. (Вам нужно прочитать/прыгать до конца)
Для нетерпеливого, вот Github Repo Для кода в этом проекте. Есть теги для каждого шага. (См. README для ссылок и описаний для каждого тега.)
Базовый
Я создал простое приложение, используя Create-React-App Отказ Он имеет сетку простых карт. Вы можете скрыть отдельные карты.
Код для этого является базовым, и результаты неинтересны. Когда пользователь нажимает глаз Кнопка значка, мы изменяем элемент Дисплей
имущество.
function Box({ word }) { const color = colors[Math.floor(Math.random() * 9)]; const [visible, setVisible] = useState(true); function hideMe() { setVisible(false); } let style = { borderColor: color, backgroundColor: color }; if (!visible) style.display = "none"; return ({" "}); }{word}{" "} {" "}
(Да, я использую крючки выше, но это не интересное использование крючков.)
Добавление анимации
Вместо того, чтобы построить свою собственную библиотеку анимации, я искал библиотеку анимации, как animate.csss Отказ Реактивно-анимированные-CSS хорошая библиотека, которая предоставляет обертку вокруг animate.css.
NPM Установка –Save React-Animated-CSS
Добавить animate.csss к index.html.
В Коробка
компонент выше, мы изменяем его рендеринг
return (); {word}
Не совсем то, что мы хотим
Но animate.csss анимает непрозрачность
и другие свойства CSS; Вы не можете сделать переход CSS на Дисплей
имущество. Таким образом, невидимый объект остается, и он занимает место в потоке документов.
Если вы Google Немного, вы найдете некоторые решения, которые предлагают использовать таймер для установки Дисплей: Нет
в конце анимации.
Итак, мы можем добавить это,
function Box({ word }) { const color = colors[Math.floor(Math.random() * 9)]; const [visible, setVisible] = useState(true); const [fading, setFading] = useState(false); function hideMe() { setFading(true); setTimeout(() => setVisible(false), 650); } let style = { borderColor: color, backgroundColor: color }; return (); } {word}
(Примечание. Продолжительность анимации по умолчанию составляет 1000 мс. Я использую 650 мс для тайм-аута, чтобы минимизировать заикание/паузу, прежде чем настроить свойство Отображение
свойство. Это вопрос предпочтений.)
И это даст нам желаемый эффект.
Создание многоразового компонента
Мы могли бы остановиться здесь, но есть две проблемы (для меня):
- Я не хочу копировать/вставлять
Анимированные
блок, стили и функции для воссоздания этого эффекта -
Коробка
Компонент смешивает различные виды логики, то есть нарушение Разделение опасений Отказ В частности,Коробка
Основная функция – сделать карту со своим содержанием. Но детали анимации смешаны.
Компонент класса
Мы можем создать традиционный компонент RACT Class для управления состоянием анимации: переключить видимость и установить тайм-аут для Дисплей
Свойство CSS.
class AnimatedVisibility extends Component { constructor(props) { super(props); this.state = { noDisplay: false, visible: this.props.visible }; } componentWillReceiveProps(nextProps, nextContext) { if (!nextProps.visible) { this.setState({ visible: false }); setTimeout(() => this.setState({ noDisplay: true }), 650); } } render() { return ({this.props.children} ); } }
а затем использовать его
function Box({ word }) { const color = colors[Math.floor(Math.random() * 9)]; const [visible, setVisible] = useState(true); function hideMe() { setVisible(false); } let style = { borderColor: color, backgroundColor: color }; return (); } {word}
Это создает многоразовый компонент, но это немного сложно. Мы можем сделать лучше.
Реактивные крючки и использование
Реактивные крючки являются новой особенностью в реакции 16.8. Они предлагают более простой подход к жизненному цикле и управлению государством в компонентах реагирования.
Useffect Крюк обеспечивает элегантную замену нашему использованию ComponentWillReceiveProps
Отказ Код проще, и мы можем снова использовать функциональный компонент.
function AnimatedVisibility({ visible, children }) { const [noDisplay, setNoDisplay] = useState(!visible); useEffect(() => { if (!visible) setTimeout(() => setNoDisplay(true), 650); else setNoDisplay(false); }, [visible]); const style = noDisplay ? { display: "none" } : null; return ({children} ); }
Есть некоторые тонкости с Useffect крюк. Это в первую очередь для побочных эффектов: изменение состояния, вызывая асинхронные функции и т. Д. В нашем случае он устанавливает внутреннюю odisplay
логический, основанный на предыдущей ценности Видимый.
Добавляя Видимый
на массив зависимостей для Useffect
наше Useffect
Крюк будет вызван только тогда, когда значение Видимый
изменения.
Я думаю Useffect гораздо лучшее решение, чем класс компонент беспорядок. ?
Повторное использование компонента: боковые панели и навкары
Все любят боковые и навкары. Итак, давайте добавим один из каждого.
function ToggleButton({ label, isOpen, onClick }) { const icon = isOpen ? ( ) : ( ); return ( ); } function Navbar({ open }) { return (); } function Sidebar({ open }) { return ( ); } function App() { const [navIsOpen, setNavOpen] = useState(false); const [sidebarIsOpen, setSidebarOpen] = useState(false); function toggleNav() { setNavOpen(!navIsOpen); } function toggleSidebar() { setSidebarOpen(!sidebarIsOpen); } return (
- Item 1
- Item 2
- Item 3
); }
Но мы не сделаны …
Мы могли бы остановиться здесь. Но как с моими предыдущими комментариями о Разделение опасений Я бы предпочел избежать смешивания Анимация невидимость
Компонент в методе рендеринга Коробка
, Боковая панель
ни Навкар
Отказ (Это также небольшое количество дублирования.)
Мы можем создать HOC. (На самом деле, я написал статью о анимации и HOCS, Как построить анимированные микроинтехии в React . ) Но HOCS обычно привлечет класс компонентов из-за государственного управления.
Но с реактивными крючками мы можем просто составить HOC (функциональный подход программирования).
function AnimatedVisibility({ visible, children, animationOutDuration, disappearOffset, ...rest }) // ... same as before } function makeAnimated( Component, animationIn, animationOut, animationInDuration, animationOutDuration, disappearOffset ) { return function({ open, className, ...props }) { return (); }; } export function makeAnimationSlideLeft(Component) { return makeAnimated(Component, "slideInLeft", "slideOutLeft", 400, 500, 200); } export function makeAnimationSlideUpDown(Component) { return makeAnimated(Component, "slideInDown", "slideOutUp", 400, 500, 200); } export default AnimatedVisibility
а затем используйте эти функциональные HOCS в App.js.
function Navbar() { return ( ); } function Sidebar() { return (); } const AnimatedSidebar = makeAnimationSlideLeft(Sidebar); const AnimatedNavbar = makeAnimationSlideUpDown(Navbar); function App() { const [navIsOpen, setNavOpen] = useState(false); const [sidebarIsOpen, setSidebarOpen] = useState(false); function toggleNav() { setNavOpen(!navIsOpen); } function toggleSidebar() { setSidebarOpen(!sidebarIsOpen); } return (
- Item 1
- Item 2
- Item 3
); }
С риском продвижения моей собственной работы я предпочитаю чистый полученный код.
Вот песочница окончательного результата.
Что теперь?
Для простых анимаций подход я описываю хорошо работает. Для более сложных случаев я бы использовал библиотеки, как Реактивное движение Отказ
Но отдельно от анимации, React Cloots предоставляют возможности создавать читаемый и простой код. Однако есть корректировка мышления. Крючки, как Useffect не являются прямой заменой для всех методов жизненного цикла. Вам нужно будет учиться и экспериментировать.
Я предлагаю смотреть на сайты, такие как usehooks.com и библиотеки, как Воспользуйтесь реагированием , коллекция крючков для различных случаев использования.