#react-hooks タグの付いた Snippet

上スクロールしたときだけ表示されるヘッダ

2021/01/04

import { useScrollPosition } from '@n8tb1t/use-scroll-position';

export const Header: React.FC = ({ children }) => {
  const [showMenu, setShowMenu] = useState(true);

  useScrollPosition(({ prevPos, currPos }) => {
    const visible = currPos.y > prevPos.y;
    setShowMenu(visible);
  }, []);

  return (
    <Center
      as="nav"
      visibility={showMenu ? 'visible' : 'hidden'}
      transition={`all 200ms ${showMenu ? 'ease-in' : 'ease-out'}`}
      transform={showMenu ? 'none' : 'translate(0, -100%)'}
    >
      {children}
    </Center>
  );
};

useScrollPosition Hooks を利用して、スクロールイベントをフックする。前回と今回の Y 座標を比較して、今回のほうが大きい(上にスクロールした)場合は、ヘッダを表示する。

hooks の引数無指定の場合は document.body の boundingClientRect が参照される。下にスクロールすると、body の top は上方向に移動する= body の Y 座標はどんどんマイナス値になっていく

表示トランジションには、Chakra UI の Collapse などを利用しても良い。ただページ遷移の際にもアニメーションしてしまって、少し違和感を覚えたので、上記の例ではトランジションを自筆している。

references

useRefの使いどき

2020/12/29

下記の 2 パターンで利用する;

  1. DOM ノードの参照を持つときに使う(e.g. <input ref={ref} />
  2. re-render を走らせたくない変数に使う(e.g. タイマー ID)

DOM ノードの参照を持つときに使う

ja.reactjs.org/docs/hooks-reference.html#useref
function TextInputWithFocusButton() {
  const inputEl = useRef(null);
  const onButtonClick = () => {
    // `current` points to the mounted text input element
    inputEl.current.focus();
  };
  return (
    <>
      <input ref={inputEl} type="text" />
      <button onClick={onButtonClick}>Focus the input</button>
    </>
  );
}

re-render を走らせたくない変数に使う

ja.reactjs.org/docs/hooks-faq.html#is-there-something-like-instance-variables
function Timer() {
  const intervalRef = useRef();

  useEffect(() => {
    const id = setInterval(() => {
      // ...
    });
    intervalRef.current = id;
    return () => {
      clearInterval(intervalRef.current);
    };
  });

  // ...
}

関数コンポーネントにおける、クラスのインスタンス変数として使える。

useRef はオブジェクトを作ってその参照を返すので、intervalRef.current の値を変更しても、intervalRef 自体が変更されないことから、re-render が走らない。この性質を利用して、クラスコンポーネントにおけるインスタンス変数のようなものとして扱うことができる。

references


Writings

blogsnippetcourse

Contact

Home©︎ suzukalight