Skip to content

Instantly share code, notes, and snippets.

@SiegeSailor
Last active April 4, 2021 06:48
Show Gist options
  • Save SiegeSailor/36f6bf6afda15f84929d110376e759fd to your computer and use it in GitHub Desktop.
Save SiegeSailor/36f6bf6afda15f84929d110376e759fd to your computer and use it in GitHub Desktop.
A React Hook to extract the desired element's real time property.

Overview

A React Hook to extract the desired element's real time property.

Example

import React from 'react';

import useElement from './use-element';

export default function Demostration() {
  const [refDiv, property] = useElement<HTMLDivElement>('offsetHeight', 0, []);
  
  return (
    <div ref={refDiv}>
      <h1>The offsetHeight of the parent div is {property}.</h1>
    </div>
  );
}
import { useRef, useEffect, useState } from 'react';
/**
* A React Hook to extract the desired element's real time property.
* @template T - The type of the element.
* @template V - The type of the property. Default is `T[keyof T]`.
* @param {keyof T} property - The property you want to extract from the element.
* @param {T[keyof T]} defaultValue - Default value for the desired property.
* @returns {[ref: React.RefObject<T>, property: typeof defaultValue]} An array consists of the ref and the property value.
*/
export function useElement<T, V = T[keyof T]>(
property: keyof T,
defaultValue: V,
dependencies: any[] = [],
ref?: RefObject<T>
): [RefObject<T>, V] {
const stringifiedDependencies = JSON.stringify(dependencies);
const refDefault = useRef<T>(null);
const refElement = ref || refDefault;
const [outcome, setOutcome] = useState<V>(defaultValue);
const setPropertyValue = useCallback(() => {
const currentPropertyValue = (refElement.current?.[
property
] as unknown) as V;
setOutcome(currentPropertyValue ?? defaultValue);
}, [property, defaultValue, refElement]);
useEffect(() => {
window.addEventListener("resize", setPropertyValue, false);
return () => {
window.removeEventListener("resize", setPropertyValue, false);
};
}, [setPropertyValue]);
useEffect(() => {
setPropertyValue();
}, [setPropertyValue, stringifiedDependencies]);
return [refElement, outcome];
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment