`useEffect` 中 ref 不会将值设置给变量。

huangapple go评论61阅读模式
英文:

ref doesnt set value to variable in useEffect

问题

我一直在学习React的入门课程,并遇到了很多问题。
首先,下面的代码在`useEffect`中没有起作用,因为某些原因,`current`的值在第一次渲染时没有被设置。

```javascript
observer.current.observe(ElemenentIGotWithRef.current) 
  useEffect(()=>{
    console.log(ElemenentIGotWithRef)
  }, [])

我在下面的代码中解决了这个问题:

  useEffect(()=>{
    if (ElemenentIGotWithRef.current)
      observer.current.observe(ElemenentIGotWithRef.current);

    return (()=>{
      observer.current.disconnect();
    })
  }, [ElemenentIGotWithRef.current])

但现在我遇到了另一个函数,由于我之前的变通方法或不正确的useEffect工作,它无法正常工作。

如何使引用在第一次渲染时设置值呢?


<details>
<summary>英文:</summary>

I&#39;ve been doing some React crash course and got in a lot of problems.
To start with, 

observer.current.observe(ElemenentIGotWithRef.current)

wasn&#39;t working in `useEffect`, because for some reasons the `current` value wasn&#39;t set at the first render. 

useEffect(()=>{
console.log(ElemenentIGotWithRef)
}, [])


console.log of my ElemenentIGotWithRef:

![](https://i.stack.imgur.com/DTBp8.png)

I solved it with

useEffect(()=>{
if (ElemenentIGotWithRef.current)
observer.current.observe(ElemenentIGotWithRef.current);

return (()=&gt;{
  observer.current.disconnect();
})

}, [ElemenentIGotWithRef.current])

But now I am stuck with another function, which doesn&#39;t work normally because of my crutch / my unproper `useEffect` work.

How could I make ref set value at the first render?

</details>


# 答案1
**得分**: 1

通常,在调用`useEffect`之前,元素已经准备好了。然而,在某些情况下(例如条件渲染),元素可能尚未准备好,`ref` 也不会立即设置。你的方法存在一个问题,即设置`ref.current`为新值不会导致重新渲染,因此可能不会在你期望的时候调用`useEffect`。在你的情况下,有其他东西会导致重新渲染(可能是用于条件渲染的状态),因此你可以避免这个问题。

你可以使用`useState`代替`useRef`,因为组件也接受一个函数作为`ref`。这将导致组件在状态更新时重新渲染与`ref`相关的部分:

```javascript
const [ref, setRef] = useState();

useEffect(() => {
  if (ref) observer.current.observe(ref);

  return () => {
    observer.current.disconnect();
  }
}, [ref])

return (
  <ComponentWithDelayedRef ref={setRef} />
)

另一种使用函数作为ref的变体是创建一个观察元素的回调,并将其传递为ref

useEffect(() => () => {
  observer.current.disconnect();
}, []);

const observe = useCallback(el => {
  observer.current.observe(el);
}, []);

return (
  <ComponentWithDelayedRef ref={observe} />
)
英文:

Usually the element is ready before useEffect is called. However, in certain situations (conditional rendering for example), the element is not ready, and the ref is not set immediately. The problem with your approach is the setting the ref.current with a new value, doesn't cause a re-render, so the useEffect might not be called when you want it. In your case, something else causes a re-render (probably the state used for the conditional render), and so you avoid this problem.

You can use useState instead of a useRef because components also accept a function as a ref. That would cause the component to re-render when the state updates with the ref:

const [ref, setRef] = useState()

useEffect(() =&gt; {
  if (ref) observer.current.observe(ref);

  return () =&gt; {
    observer.current.disconnect();
  }
}, [ref])

return (
  &lt;ComponentWithDelayedRef ref={setRef} /&gt;
)

Another variation on the function as a ref idea, is to create a callback to observe the element, and pass it as the ref:

useEffect(() =&gt; () =&gt; {
  observer.current.disconnect();
}, [])

const observe = useCallback(el =&gt; {
  observer.current.observe(ref)
}, []);

return (
  &lt;ComponentWithDelayedRef ref={observe} /&gt;
)

huangapple
  • 本文由 发表于 2023年3月3日 20:57:59
  • 转载请务必保留本文链接:https://go.coder-hub.com/75627388.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定