0.2.0 • Published 1 year ago

@susisu/react-use-source-sink v0.2.0

Weekly downloads
345
License
MIT
Repository
github
Last release
1 year ago

@susisu/react-use-source-sink

CI

# npm
npm i @susisu/react-use-source-sink
# yarn
yarn add @susisu/react-use-source-sink
# pnpm
pnpm add @susisu/react-use-source-sink

Usage

import React, { useEffect } from "react";
import { useSourceSink } from "@susisu/react-use-source-sink";

const Hello: React.FC = () => {
  const [source, sink] = useSourceSink<HTMLElement | null>(null);
  useEffect(() => {
    const elem = source();
    // ...
  });
  return (
    <p ref={sink}>Hello!</p>
  );
};

Why?

The following code does not pass the type check.

import React, { useRef } from "react";

const Hello: React.FC = () => {
  const ref = useRef<HTMLElement | null>(null);
  return (
    <p ref={ref}>Hello!</p>
  );
};

This is because a reference created by useRef is both readable and writable, and basically invariant in terms of types, which means it cannot be up- nor down-casted. A reference to HTMLElement cannot be passed to the ref prop of a p element, which requires a reference to HTMLParagraphElement.

To pass the type check, we can use a callback ref, which is basically contravariant and can be safely passed to a concrete element.

import React, { useRef, useCallback } from "react";

const Hello: React.FC = () => {
  const ref = useRef<HTMLElement | null>(null);
  const callbackRef = useCallback((elem: HTMLElement | null): void => {
    ref.current = elem;
  }, []);
  return (
    <p ref={callbackRef}>Hello!</p>
  );
};

useSourceSink simplifies this boilerplate.

License

MIT License

Author

Susisu (GitHub, Twitter)

0.2.0

1 year ago

0.1.6

3 years ago

0.1.5

5 years ago

0.1.4

5 years ago

0.1.3

5 years ago

0.1.2

6 years ago

0.1.1

6 years ago

0.1.0

6 years ago