在 Gatsby 中使用 React 挂钩

JavaScript将函数视为一等公民。我们可以在React中看到这一点,现在比以往任何时候都多,在版本16.8中引入了Hooks。它们允许状态操作和对功能组件的副作用。

在其核心,盖茨比使用香草反应与其所有功能。因此,这意味着Hooks可以与简单的port语句一起使用。让我们来看看我们可以利用它们的一些方式。

入门

特别是没有任何东西需要我们安装。然而,有必要拥有最新版本的Reaction和Gatsby或至少v16.8+。我们可以通过检查我们的package.json并找到我们已经安装的版本来做到这一点。

如果您需要升级,我们可以运行以下命令:

有了这些,我们就可以出发了。

使用钩子

让我们设置一个带有滚动状态和下拉菜单的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]将提供相同的功能。

钩子和用户输入

我们将进一步介绍这个示例,并添加一个可通过切换按钮访问的下拉菜单。我们可以保留已创建的大部分内容,只需修改状态更改属性即可。该属性将重命名为statesetState,同时获取具有各种状态变量的对象。

在这种情况下,更新状态会略有不同。首先,我们需要将先前的状态作为扩展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-hiddendata-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

Published At
Categories with 技术
Tagged with
comments powered by Disqus