Thứ tư, 22/01/2020 | 00:00 GMT+7

Sử dụng React Hooks trong Gatsby


JavaScript coi các hàm như công dân hạng nhất. Và ta có thể thấy điều này trong React bây giờ hơn bao giờ hết với sự ra đời của Hooks trong version 16.8. Chúng cho phép thao tác trạng thái và tác dụng phụ lên các thành phần chức năng.

Về cốt lõi, Gatsby sử dụng vanilla React với tất cả các tính năng của nó. Vì vậy, điều này nghĩa là Hooks có sẵn để sử dụng với một câu lệnh import đơn giản. Ta hãy xem xét một số cách ta có thể tận dụng chúng.

Bắt đầu

Đặc biệt, ta sẽ không cần cài đặt bất cứ thứ gì. Tuy nhiên, bạn cần phải có version React và Gatsby mới nhất hoặc ít nhất là v16.8 +. Ta có thể thực hiện bằng cách kiểm tra package.json của ta và tìm version ta đã cài đặt.

Nếu bạn cần nâng cấp, ta có thể chạy như sau:

$ npm install react@16.8.0 react-dom@16.8.0
# or
$ yarn add react@16.8.0 react-dom@16.8.0

Như vậy, ta nên đi.

Sử dụng Hooks

Hãy cài đặt thành phần header.js với trạng thái cuộn và menu thả xuống.

Thành phần của ta sẽ là một tiêu đề cố định ở trên cùng, vẫn giữ nguyên vị trí trong khi user cuộn qua trang, nhưng hiển thị bóng hộp khi user không ở trên cùng. Điều đó nghĩa là trạng thái của ta sẽ là một boolean chuyển đổi dựa trên vị trí cửa sổ hiện tại. Ta sẽ sử dụng các API root để xác định vị trí cửa sổ.

src / components / header.js
import React, { useState, useEffect } from 'react';
import { Link } from 'gatsby';

const Header = () => {
  // determined if page has scrolled and if the view is on mobile
  const [scrolled, setScrolled] = useState(false);

  // change state on scroll
  useEffect(() => {
    const handleScroll = () => {
      const isScrolled = window.scrollY > 10;
      if (isScrolled !== scrolled) {
        setScrolled(!scrolled);
      }
    };

    document.addEventListener('scroll', handleScroll, { passive: true });

    return () => {
      // clean up the event handler when the component unmounts
      document.removeEventListener('scroll', handleScroll);
    };
  }, [scrolled]);

  return (
    <header data-active={scrolled}>
      <Link to="/">React Hooks on Gatsby</Link>
      <nav>
        <Link to="/about/">About</Link>
        <Link to="/contact/">Contact Us</Link>
      </nav>
    </header>
  );
};

export default Header;

Thuộc tính window.scrollY trả về số pixel đã chuyển theo chiều dọc trên cuộn. Ta so sánh giá trị đó với 10 pixel và ta nhận được giá trị boolean sẽ cho ta biết liệu user đã di chuyển tài liệu hay chưa. Sau đó, ta bao bọc thuộc tính điều kiện xung quanh một chức năng cập nhật trạng thái scrolled khi nào user cuộn qua trang web. Hàm này sau đó được chuyển cho một trình nghe sự kiện trên tài liệu.

Tất cả những điều này sẽ nằm bên trong hook useEffect , nó sẽ trả về một removeEventListener trên tài liệu để dọn dẹp trình xử lý sự kiện khi thành phần ngắt kết nối. useEffect cho phép ta thực hiện các hiệu ứng phụ trên thành phần của ta . Theo mặc định, hiệu ứng sẽ kích hoạt sau mỗi lần kết xuất hoàn thành, tuy nhiên, ta có thể chuyển đối số thứ hai dưới dạng một mảng giá trị mà hiệu ứng phụ thuộc vào để kích hoạt. Trong trường hợp của ta , [scrolled] .

Cùng với đó, ta có thể thêm thuộc tính nhận dạng vào HTML của bạn để xác định trạng thái của phần tử. Ta sẽ sử dụng thuộc tính data-active với boolean từ trạng thái scrolled . Và trong CSS của ta , ta có thể thêm hiệu ứng box-shadow bằng công cụ chọn thuộc tính.

src / styles / main.scss
header {
  position: fixed;
  top: 0;
  transition: box-shadow .3s ease;
  width: 100%;

  &[data-active='true'] {
    box-shadow: 0 2px 8px rgba(152,168,188,.2);
  }
}

Có thể sử dụng cùng một kiểu dáng với các thành phần được tạo kiểu . Việc swap bộ chọn header với mẫu được gắn thẻ của thành phần theo nghĩa đen sẽ cung cấp chức năng tương tự.

Hooks và đầu vào của user

Ta sẽ xem xét ví dụ này thêm một bước nữa và thêm một menu thả xuống có thể truy cập được thông qua nút bật tắt. Ta có thể giữ hầu hết những gì đã được tạo và chỉ cần sửa đổi các thuộc tính thay đổi trạng thái. Thuộc tính sẽ được đổi tên thành statesetState trong khi lấy một đối tượng với các biến trạng thái khác nhau của ta .

Trạng thái cập nhật sẽ hơi khác trong trường hợp này. Đầu tiên, ta cần chuyển trạng thái trước đó dưới dạng toán tử spread , tiếp theo là giá trị được cập nhật. Điều này là do, không giống như các thành phần lớp, các thành phần chức năng sẽ thay thế các đối tượng được cập nhật thay vì hợp nhất chúng.

src / components / header.js
import React, { useState, useEffect } from 'react';
import { Link } from 'gatsby';

import Dropdown from './dropdownMenu';

const Header = () => {
  // determined if page has scrolled and if the view is on mobile
  const [state, setState] = useState({
    scrolled: false,
    visible: false,
  });

  // change state on scroll
  useEffect(() => {
    const handleScroll = () => {
      const isScrolled = window.scrollY > 10;
      if (isScrolled !== state.scrolled) {
        setState({
          ...state,
          scrolled: !state.scrolled,
        });
      }
    };
    document.addEventListener('scroll', handleScroll, { passive: true });
    return () => {
      // clean up the event handler when the component unmounts
      document.removeEventListener('scroll', handleScroll);
    };
  }, [state.scrolled]);

  // toggle dropdown visibility
  const toggleVisibility = () => {
    setState({
      ...state,
      visible: !state.visible,
    });
  };

  return (
    <header data-active={state.scrolled}>
      <Link to="/">React Hooks on Gatsby</Link>
      <nav>
        <Link to="/about/">About</Link>
        <Link to="/contact/">Contact Us</Link>
        <button onClick={toggleVisibility} type="button">
          Solutions
        </button>
        <Dropdown
          aria-hidden={!state.visible}
          data-active={state.visible}
        />
      </nav>
    </header>
  );
};

export default Header;

Ta muốn user nhấp vào một nút sẽ mở ra một menu bổ sung. Khi nút Giải pháp được nhấp, nó sẽ chuyển đổi boolean visible . Boolean này được chuyển đến các thuộc tính aria-hiddendata-active để sử dụng trong CSS của ta .

src / styles / main.scss
// the section element is our <Dropdown /> component

header {
  top: 0;
  transition: box-shadow .3s ease;

  &[data-active='true'] {
    box-shadow: 0 2px 8px rgba(152,168,188,.2);
  }

  &,
  section {
    position: fixed;
    width: 100%;
  }

  nav,
  section {
    overflow: hidden;
  }

  section {
    height: 0;
    left: 0;
    opacity: 0;
    right: 0;
    top: 5.5rem;
    transition: all .3s ease-in-out;
    visibility: hidden;

    &[data-active='true'] {
      height: auto;
      opacity: 1;
      visibility: visible;
    }
  }
}

Kết luận

Với Hooks, ta nhận được tất cả lợi ích của các thành phần lớp với sự quen thuộc của các thành phần chức năng. Gatsby tận dụng tối đa điều đó. Tôi khuyên bạn nên xem qua tất cả các Hook có sẵn trong tài liệu React. Và bạn thậm chí có thể đi sâu vào xây dựng móc của riêng mình !


Tags:

Các tin liên quan