Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to use useEffect with forwardRef in typescript?

This is my code:

import React from 'react';

type shapeTable = {
  data: string[][];
  onMount?: (tableWidth: string) => void;
};

 type Ref = HTMLTableElement;

 const Table = React.forwardRef<Ref, shapeTable>(({ data, onMount }, ref) => {
  React.useEffect(() => {
    console.log('ref = ', ref);
    if (ref) {
      console.log('ref.current = ', ref.current);
    }
    // const $table = ref.current;
    // if (ref && onMount) {
    //   const tableWidth:string = window.getComputedStyle($table).getPropertyValue("width");
    //   onMount(tableWidth);
    // }
  });
  return data.length ? (
    <table ref={ref}>
      <tbody>
        {data.slice(1).map(tr => (
          <tr>
            {tr.map(item => (
              <td>{item}</td>
            ))}
          </tr>
        ))}
      </tbody>
    </table>
  ) : null;
});

Error

It fails on ref.current

It seems to struggle with ref.current.

I'm struggling to force the Ref to be only "HTMLTableElement".

Any suggestions, thanks?

like image 439
Steve Tomlin Avatar asked Mar 15 '26 09:03

Steve Tomlin


1 Answers

Here's the working example

const { useState, useRef, createRef, forwardRef, useEffect } = React;

const Table = forwardRef((props, ref) => {
  useEffect(() => {
    console.log('ref: ', ref && ref.current);
  }, [ref])

  return <table ref={ref}>
    {props.children}
  </table>
})


const App = () => {
  const ref = useRef();

  return <Table ref={ref}>
    <tbody></tbody>
  </Table>
}

ReactDOM.render(
    <App />,
    document.getElementById('root')
  );
<script src="https://unpkg.com/react/umd/react.development.js"></script>
<script src="https://unpkg.com/react-dom/umd/react-dom.development.js"></script>
<script src="https://unpkg.com/babel-standalone@6/babel.min.js"></script>
<div id="root"></div>

--Edit

Quite a horrifying definition when you look at resolved type of ref in intellisense

((instance: HTMLTableElement | null) => void) | React.MutableRefObject<HTMLTableElement | null> | null

That means you have to check if ref is defined and ref is not a function

And if ref.current is also defined, just to keep && going

...or just cast to any and don't bother.

Up to you

const Table = React.forwardRef<HTMLTableElement >((props, ref) => {

  React.useEffect(() => {
    if(ref && typeof ref !== "function" && ref.current) {

      console.log('ref: ', ref.current);
      // ref.current.getBoundingClientRect()
    }

  }, [ref])

  return <table ref={ref}>
    {props.children}
  </table>
})
like image 77
Józef Podlecki Avatar answered Mar 16 '26 21:03

Józef Podlecki



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!