题意:React 组件折叠问题:在解析 URL 时 Ref 未初始化
问题背景:
I have a component that should expand if it is selected. Here's my current approach:
我有一个组件,当它被选中时应该展开。以下是我当前的实现方法:
<Element
ref={elementRef}
style={{ height: isSelected ? `${elementRef.current.scrollHeight}px` : '0px' }}
/>
Now, I've added routing, which parses the URL. For example, if I am at host:port/selected/1, the first element should automatically expand.
现在,我添加了路由功能来解析URL。例如,如果我访问 `host:port/selected/1`,第一个元素应该自动展开。
The URL parsing works fine, but it happens just at the beginning of the creation of the website.
URL解析工作正常,但它只发生在网站创建的最初阶段。
This results that while the function is returning the JSX-Element, isSelected
evaluates to true
which causes an issue because the ref has not yet been initialized. (elementRef.current
is null
)
这导致在函数返回JSX元素时,`isSelected` 被评估为 `true`,这引发了一个问题,因为 `ref` 尚未初始化(`elementRef.current` 为 `null`)。
Or to put it in different words: the scrollHeight of a non-rendered object doesn't make sense and React tells me so.
换句话说:未渲染对象的 `scrollHeight` 没有意义,React 告诉了我这一点。
I'm struggling to figure out the best way to handle this. I think I need to use a different hook than useRef, but which one?
我正在努力找出解决这个问题的最佳方法。我觉得我需要使用一个不同于 `useRef` 的 hook,但应该用哪个呢?
I tried using useState
with the dependencies isSelected
and elementRef
which is not fired after rendering, but before (or during).
我尝试使用 `useState`,并将 `isSelected` 和 `elementRef` 作为依赖,但它在渲染之后没有触发,而是在渲染之前(或期间)触发。
问题解决:
I managed to fix it by using useCallback
我通过使用 `useCallback` 成功解决了这个问题。
So instead of
所以代替原来的方法,
<Element
ref={elementRef}
style={{ height: isSelected ? `${elementRef.current.scrollHeight}px` : '0px' }}
/>
I have achieved it by using the useCallback
hook which is called after each rendering pass:
我通过使用 `useCallback` 钩子实现了这一点,它会在每次渲染后被调用:
const detailRef = useCallback((element) => {
if (!element) {
return;
}
element.style.height = isExpanded ? `${element.scrollHeight}px` : '0px';
}, [isExpanded]);
// ...
return (
<Element ref={detailRef} />
);