开发者问题收集

如何在 React 中使用 useRef 更新高度 prop?

2021-10-16
4482

我需要动态定义 HTML 元素的大小并将其高度设置为组件。我尝试使用 useRef 执行此操作,但由于状态包含前一个值(而不是当前值),因此它无法按预期工作。有人可以帮我吗?

这是链接:CodeSandBox https://codesandbox.io/s/happy-water-fzqk8?file=/src/App.js

下面的代码运行正常,但有一个硬​​核变量 HEIGHT 定义选项卡的高度。我的任务是使高度动态化

import { useState } from 'react';

const HEIGHT = {
  0: 200,
  1: 400,
  2: 800,
}

function App() {
  const [tab, setTab] = useState(0);

  const switchTab = (id) => {
    setTab(id);
  };

  return (
    <div
      style={{
        margin: '100px auto',
        backgroundColor: 'pink',
        width: '400px',
        overflow: 'hidden',
        height: HEIGHT[tab], // need this to be dynamic not hardcored
      }}
    >
      <div>
        {tab === 0 && (
          <div style={{ display: 'flex', flexDirection: 'column' }}>
            <h2>Tab 1</h2>
            <input />
            <button onClick={() => switchTab(1)}>Go to tab 2</button>
            <p>Some text here</p>
          </div>
        )}
        {tab === 1 && (
          <div style={{ display: 'flex', flexDirection: 'column' }}>
            <h2>Tab 2</h2>
            <input />
            <button onClick={() => switchTab(0)}>Go to tab 1</button>
            <button onClick={() => switchTab(2)}>Go to tab 3</button>
            <p>
              Some more text here. Some more text here. Some more text here. Some more text here.
              Some more text here. Some more text here. Some more text here
            </p>
          </div>
        )}

        {tab === 2 && (
          <div style={{ display: 'flex', flexDirection: 'column' }}>
            <h2>Tab 3</h2>
            <input />
            <button onClick={() => switchTab(0)}>Go to tab 1</button>
            <button onClick={() => switchTab(1)}>Go to tab 2</button>
          </div>
        )}
      </div>
    </div>
  );
}

我尝试了:

  1. 添加了 useRef 和保存元素高度的状态
    const elRef = useRef(0);
    const [height, setHeight] = useState(elRef.current.offsetHeight);
  1. 添加了计算元素大小然后将其设置为状态变量的函数
      const resizeHeight = useCallback(() => {
        const size = elRef.current.offsetHeight;
        setHeight(size)
      }, [elRef]);
  1. 以这种方式将状态高度添加到样式中
    <div
      style={{
        margin: '100px auto',
        backgroundColor: 'pink',
        width: '400px',
        overflow: 'hidden',
        height: height, // it should be the element size
      }}
    >

它不起作用(( 这是链接...状态高度 - 未定义 https://codesandbox.io/s/objective-brown-zq7ih?file=/src/App.js

在此处输入图片描述

1个回答

您可以在 switchTab 处理程序中轻松更新 elRef 引用,而无需使用 useEffect 和任何 useCallback 挂钩:

const elRef = useRef(0);

const SwitchTab = (id) => {
  setTab(id);
  setHeight(elRef.current.offsetHeight)
};

现在将 elRef 传递给 target divref 属性:

  return (
    <div
      style={{
        margin: '100px auto',
        backgroundColor: 'pink',
        width: '400px',
        overflow: 'hidden',
        height: HEIGHT[tab],
      }}
    >
      <div ref={elRef}>    // ------------------------> added here
        {tab === 0 && (
          <div style={{ display: 'flex', flexDirection: 'column' }}>
            <h2>Tab 1</h2>
            <input />
            <button onClick={() => switchTab(1)}>Go to tab 2</button>
            <p>Some text here</p>
          </div>
        )}
        {tab === 1 && (
          <div style={{ display: 'flex', flexDirection: 'column' }}>
            <h2>Tab 2</h2>
            <input />
            <button onClick={() => switchTab(0)}>Go to tab 1</button>
            <button onClick={() => switchTab(2)}>Go to tab 3</button>
            <p>
              Some more text here. Some more text here. Some more text here. Some more text here.
              Some more text here. Some more text here. Some more text here
            </p>
          </div>
        )}

        {tab === 2 && (
          <div style={{ display: 'flex', flexDirection: 'column' }}>
            <h2>Tab 3</h2>
            <input />
            <button onClick={() => switchTab(0)}>Go to tab 1</button>
            <button onClick={() => switchTab(1)}>Go to tab 2</button>
          </div>
        )}
      </div>
    </div>
  );
nima
2021-10-16