JavaScript将函数视为一等公民。我们可以在React中看到这一点,现在比以往任何时候都多,在版本16.8中引入了Hooks。它们允许状态操作和对功能组件的副作用。
在其核心,盖茨比使用香草反应与其所有功能。因此,这意味着Hooks可以与简单的port
语句一起使用。让我们来看看我们可以利用它们的一些方式。
入门
特别是没有任何东西需要我们安装。然而,有必要拥有最新版本的Reaction和Gatsby或至少v16.8+。我们可以通过检查我们的package.json并找到我们已经安装的版本来做到这一点。
如果您需要升级,我们可以运行以下命令:
1$ npm install [email protected] [email protected]
2# or
3$ yarn add [email protected] [email protected]
有了这些,我们就可以出发了。
使用钩子
让我们设置一个带有滚动状态和下拉菜单的header.js
组件。
我们的组件将是一个位于顶部的固定标题,当用户滚动页面时,它将保持不变,但当用户不在顶部时,它将显示一个框状阴影。这意味着我们的状态将是一个布尔值,它根据当前窗口的位置进行切换。我们将使用本机API来确定窗口位置。
1[label src/components/header.js]
2import React, { useState, useEffect } from 'react';
3import { Link } from 'gatsby';
4
5const Header = () => {
6 // determined if page has scrolled and if the view is on mobile
7 const [scrolled, setScrolled] = useState(false);
8
9 // change state on scroll
10 useEffect(() => {
11 const handleScroll = () => {
12 const isScrolled = window.scrollY > 10;
13 if (isScrolled !== scrolled) {
14 setScrolled(!scrolled);
15 }
16 };
17
18 document.addEventListener('scroll', handleScroll, { passive: true });
19
20 return () => {
21 // clean up the event handler when the component unmounts
22 document.removeEventListener('scroll', handleScroll);
23 };
24 }, [scrolled]);
25
26 return (
27 <header data-active={scrolled}>
28 <Link to="/">React Hooks on Gatsby</Link>
29 <nav>
30 <Link to="/about/">About</Link>
31 <Link to="/contact/">Contact Us</Link>
32 </nav>
33 </header>
34 );
35};
36
37export default Header;
window.scrollY
属性返回在滚动上垂直经过的像素数。我们将该值与10个像素进行比较,得到一个布尔值,它将告诉我们用户是否移动了文档。然后,我们将条件属性包装在一个函数周围,该函数在用户滚动浏览站点时更新`scroll‘状态。然后将该函数传递给文档上的事件侦听器。
所有这些都将驻留在useEffect挂钩中,该挂钩将在卸载组件时在文档上返回一个emoveEventListener
以清理事件处理程序。useEffect
挂钩允许我们对组件执行副作用。默认情况下,效果将在每次完成渲染后触发,但是,我们可以将第二个参数作为触发效果所依赖的值数组来传递。在我们的例子中,是[滚动]
。
这样,我们就可以向我们的HTML添加一个标识属性来确定元素的状态。我们将使用带有来自scllled
状态的布尔值的data-active
属性。在我们的css中,我们可以使用属性选择器添加box-shadow
效果。
1[label src/styles/main.scss]
2header {
3 position: fixed;
4 top: 0;
5 transition: box-shadow .3s ease;
6 width: 100%;
7
8 &[data-active='true'] {
9 box-shadow: 0 2px 8px rgba(152,168,188,.2);
10 }
11}
styled-components.可以使用相同的样式将Header
选择器替换为组件的标记模板literal]将提供相同的功能。
钩子和用户输入
我们将进一步介绍这个示例,并添加一个可通过切换按钮访问的下拉菜单。我们可以保留已创建的大部分内容,只需修改状态更改属性即可。该属性将重命名为state
和setState
,同时获取具有各种状态变量的对象。
在这种情况下,更新状态会略有不同。首先,我们需要将先前的状态作为扩展operator,,后跟更新值来传递。这是因为,与类组件不同,函数组件将替换更新的对象,而不是合并它们。
1[label src/components/header.js]
2import React, { useState, useEffect } from 'react';
3import { Link } from 'gatsby';
4
5import Dropdown from './dropdownMenu';
6
7const Header = () => {
8 // determined if page has scrolled and if the view is on mobile
9 const [state, setState] = useState({
10 scrolled: false,
11 visible: false,
12 });
13
14 // change state on scroll
15 useEffect(() => {
16 const handleScroll = () => {
17 const isScrolled = window.scrollY > 10;
18 if (isScrolled !== state.scrolled) {
19 setState({
20 ...state,
21 scrolled: !state.scrolled,
22 });
23 }
24 };
25 document.addEventListener('scroll', handleScroll, { passive: true });
26 return () => {
27 // clean up the event handler when the component unmounts
28 document.removeEventListener('scroll', handleScroll);
29 };
30 }, [state.scrolled]);
31
32 // toggle dropdown visibility
33 const toggleVisibility = () => {
34 setState({
35 ...state,
36 visible: !state.visible,
37 });
38 };
39
40 return (
41 <header data-active={state.scrolled}>
42 <Link to="/">React Hooks on Gatsby</Link>
43 <nav>
44 <Link to="/about/">About</Link>
45 <Link to="/contact/">Contact Us</Link>
46 <button onClick={toggleVisibility} type="button">
47 Solutions
48 </button>
49 <Dropdown
50 aria-hidden={!state.visible}
51 data-active={state.visible}
52 />
53 </nav>
54 </header>
55 );
56};
57
58export default Header;
我们希望让用户单击一个按钮,将打开一个额外的菜单。当单击 Solutions 按钮时,它将切换visible
布尔值。这个布尔值被传递给aria-hidden
和data-active
属性,以便在CSS中使用。
1[label src/styles/main.scss]
2// the section element is our <Dropdown /> component
3
4header {
5 top: 0;
6 transition: box-shadow .3s ease;
7
8 &[data-active='true'] {
9 box-shadow: 0 2px 8px rgba(152,168,188,.2);
10 }
11
12 &,
13 section {
14 position: fixed;
15 width: 100%;
16 }
17
18 nav,
19 section {
20 overflow: hidden;
21 }
22
23 section {
24 height: 0;
25 left: 0;
26 opacity: 0;
27 right: 0;
28 top: 5.5rem;
29 transition: all .3s ease-in-out;
30 visibility: hidden;
31
32 &[data-active='true'] {
33 height: auto;
34 opacity: 1;
35 visibility: visible;
36 }
37 }
38}
结论
有了Hooks,我们既可以获得类组件的所有好处,也可以获得功能组件的熟悉程度。盖茨比充分利用了这一点。我建议您看看Reaction文档中的所有钩子available。你甚至可以一头扎进构建自己的hooks!