简体   繁体   English

ref 上的事件处理程序如何在渲染之间持续存在?

[英]How does event handler on ref in react persist between renders?

In react if you have a ref and you attach a DOM event using如果你有一个 ref 并且你使用附加一个 DOM 事件

ref.current.onclick = eventHandler

I understand that react guarantees that ref will hold a reference to the DOM element but how does the event handler on the DOM node persist between re-renders as DOM node can change.我知道反应保证 ref 将持有对 DOM 元素的引用,但是 DOM 节点上的事件处理程序如何在重新渲染之间持续存在,因为 DOM 节点可以更改。

Because on every re-render, React regenerates the handler and attach it to the new DOM node.因为在每次重新渲染时,React 都会重新生成处理程序并将其附加到新的 DOM 节点。

You would write a component like this:你会写一个这样的组件:

export default function App() {
  return (
    <button
      onClick={(e) => {
        console.log(e.target);
      }}
    >
      button
    </button>
  );
}

And every re-render could cause React to perform something like this:并且每次重新渲染都可能导致 React 执行如下操作:

// Call `App` as a funtion
// Every thing inside the `App` funtion body will be executed again
// So you get a new onClick handler inside the funtion which will be attach to the new DOM node
const element = App();

render(element);

As for Ref , it's similar.至于Ref ,它是相似的。 When you call useRef , you get an object like this: { current: null }当你调用useRef时,你会得到一个像这样的 object: { current: null }

// `ref` is passing to the component on every re-render
// `ref` object dose not change on every re-render, but it's property `current` will be assigned with the new DOM node.
<button ref={ref}>button</button>

This is an extremely simplified code, and does not represent how React actually works, but it makes good point.这是一个极其简化的代码,并不代表 React 的实际工作方式,但它说明了一点。

There seems to be a misunderstanding.好像有什么误会。 When the DOM node changes your event handler is not preserved.当 DOM 节点更改时,您的事件处理程序不会被保留。 That is the responsibility of your code alone.这仅是您的代码的责任。 But the DOM node does not change with every render.但是 DOM 节点不会随着每次渲染而改变。 React compares your returned result with the previous result and decides which DOM nodes need to be replaced. React 将您返回的结果与之前的结果进行比较,并决定需要替换哪些 DOM 节点。

If you want to use a native event you have to make sure to attach and detach the event handler whenever the node changes.如果要使用本机事件,则必须确保在节点更改时附加和分离事件处理程序。

const rootChanged = useCallback(element => element.addEventListener(type, listener),[]);

// ...

<div ref={rootChanged} key={someVolatileKey}>
  // ...
</div>

When the key changes for example React will create a new node for the root element.例如,当key更改时,React 将为根元素创建一个新节点。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM