在 运行 useEffect 填充初始状态后反应 useRef 返回 null

React useRef returning null after running a useEffect to fill the initial state

我正在尝试使用 React 的 useRef 将我的自定义组件挂接到 ref,以便使用 html2canvas 并将元素呈现为 canvas.

const dataLetters = {
  headers: [
    'A',
    'B',
    'C',
    'D',
    'E',
    'F',
    'G'
  ],
  rows: [
    ['A', 'B', 'C', 'D', 'E', 'F', 'G'],
  ]
};

export default function LettersPage() {
  // refs
  const LettersTableRef = useRef(null);

  useEffect(() => {
    console.log('letter ref');
    console.log(LettersTableRef.current); // same result when logging LettersTableRef
  }, [LettersTableRef]);

  return (
    <Page>
      <CustomizedTable ref={LettersTableRef} data={dataLetters } />
    </Page>
  );
}

然而,当我 运行 这段代码时,控制台在记录“letter ref”后记录 null。 CustomizedTable 只是获取数据并构建行和一个 header 给出的信息 - 没什么特别的。

我是 React 新手 javascript。我读过我可以在 javascript 中给一个元素一个 id - 我不知道如何在反应上下文中做到这一点,并且我试图坚持在 React 中使用 React 而不是普通 js 的做法。

请让我知道我做错了什么!

-----已更新以添加 CustomizeTable 的代码----

import Table from '@mui/material/Table';
import TableBody from '@mui/material/TableBody';
import TableCell, { tableCellClasses } from '@mui/material/TableCell';
import TableContainer from '@mui/material/TableContainer';
import TableHead from '@mui/material/TableHead';
import TableRow from '@mui/material/TableRow';

export default function CustomizedTables({ data, id }) {
  return (
    <TableContainer>
      <Table>
        <TableHead>
          <TableRow>
            {data.headers.map((header) => (
              <TableCell>{header}</TableCell>
            ))}
          </TableRow>
        </TableHead>
        <TableBody>
          {data.rows.map((row) => (
            <TableRow>
              {row.map((datum) => (
                <TableCell>{datum}</TableCell>
              ))}
            </TableRow>
          ))}
        </TableBody>
      </Table>
    </TableContainer>
  );
}

您应该在浏览器的控制台上再次检查。关于 refeach child in a list should have a unique key...

应该有一些错误

使用 refs 是 React 中的高级主题,您基本上可以获得指向对象的指针。这将与对 class-组件或 HTML-元素的引用一起使用,但不直接与功能组件一起使用。为此,您必须使用 forwardRef 将您的功能组件包装在里面。

我已经在此处修复了您的代码:https://codesandbox.io/s/vigorous-dew-u2bm9?file=/src/CustomizedTable.jsx

使用 forwardRef 您可以设置对任何子元素的引用,以便外部组件可以使用 useRef 直接访问它。 useImperativeHandle 还有一些其他方法可以获取方法作为参考,但这会更高级。

const CustomizedTables = forwardRef(({ data, id }, ref) => (
    <TableContainer ref={ref}>
      ....
    </TableContainer>
));

我强烈推荐有关此主题的官方文档:https://reactjs.org/docs/hooks-reference.html