我应该使用 ref 还是 findDOMNode 来获取元素的 React 根 dom 节点?

问题描述 投票:0回答:2

我想要进行一些 dom 节点大小计算(渲染的 DOM 节点的顶部、底部和大小属性)

我现在正在做的,在

componentDidUpdate
方法上是调用 findDOMNode :

 componentDidUpdate() {
        var node = ReactDOM.findDOMNode(this);

        this.elementBox = node.getBoundingClientRect();
        this.elementHeight = node.clientHeight;
        // Make calculations and stuff
}

这工作正常,但我有点担心性能,并对最佳实践做出反应。有几个地方讨论了使用

ref
属性而不是 findDOMNode,但它们都是针对子 dom 元素的,就我而言,我只想要组件的根 DOM 节点。

使用 ref 的替代方案可能如下所示:

render(){
   return (
            <section // container
                ref={(n) => this.node = n}>
                 // Stuff
            </section>
}
 componentDidUpdate() {

        this.elementBox = this.node.getBoundingClientRect();
        this.elementHeight = this.node.clientHeight;
        // Make calculations and stuff
}

说实话,将 ref 回调附加到我的根 dom 节点只是为了获取它的引用,这对我来说并不正确。

此案例的最佳实践是什么?哪一个性能更好?

javascript reactjs dom react-dom
2个回答
15
投票

如果我参考文档(https://facebook.github.io/react/docs/react-dom.html#finddomnode),

findDOMNode
似乎更像是一个技巧而不是真正的选择。裁判似乎是最好的选择。 doc 实现了您在此处给出的相同草案(使用
ref={(n) => this.node = n}


0
投票

这是我们如何在现代 React 中做到这一点。由于

findDOMNode
在 React 18 中已经已弃用,因此我们应该根据 API 文档这样做。

参考:https://react.dev/reference/react-dom/findDOMNode#alternatives

类组件:

 constructor(props) {
    super(props);
    this.nodeRef = React.createRef(); // Create a ref
  }

  componentDidUpdate() {
    const node = this.nodeRef.current;
    this.elementBox = node.getBoundingClientRect();
    this.elementHeight = node.clientHeight;
    // Make calculations and stuff
  }

  render() {
    return (
      <section ref={this.nodeRef} >

功能组件:

  const nodeRef = useRef(null);
  const [elementBox, setElementBox] = useState(null);
  const [elementHeight, setElementHeight] = useState(0);

  useEffect(() => {
    if (nodeRef.current) {
      const node = nodeRef.current;
      setElementBox(node.getBoundingClientRect());
      setElementHeight(node.clientHeight);
      // Make calculations and stuff
    }
  }, [/* dependencies */]);

  return (
    <section ref={nodeRef} >
© www.soinside.com 2019 - 2024. All rights reserved.