typescript.react.best-practice.react-find-dom.react-find-dom

profile photo of semgrepsemgrep
Author
4,056
Download Count*

findDOMNode is an escape hatch used to access the underlying DOM node. In most cases, use of this escape hatch is discouraged because it pierces the component abstraction.

Run Locally

Run in CI

Defintion

rules:
  - id: react-find-dom
    pattern-either:
      - pattern: |
          findDOMNode(...)
      - pattern: |
          $DOM.findDOMNode(...)
    message: findDOMNode is an escape hatch used to access the underlying DOM node.
      In most cases, use of this escape hatch is discouraged because it pierces
      the component abstraction.
    metadata:
      references:
        - https://react.dev/reference/react-dom/findDOMNode
        - https://github.com/yannickcr/eslint-plugin-react/issues/678#issue-165177220
      category: best-practice
      technology:
        - react
      license: Commons Clause License Condition v1.0[LGPL-2.1-only]
    languages:
      - typescript
      - javascript
    severity: WARNING

Examples

react-find-dom.jsx

class TestComponent1 extends Component {
  componentDidMount() {
        // ruleid: react-find-dom
    findDOMNode(this).scrollIntoView();
  }

  render() {
    return <div />
  }
}

class OkComponent1 extends Component {
  componentDidMount() {
        // ok: react-find-dom
    this.node.scrollIntoView();
  }

  render() {
    return <div ref={node => this.node = node} />
  }
}

class TestComponent1 extends Component {
  componentDidMount() {
        // ruleid: react-find-dom
    ReactDOM.findDOMNode(this.refs.something).scrollIntoView();
  }

  render() {
    return (
      <div>
        <div ref='something' />
      </div>
    )
  }
}

class OkComponent2 extends Component {
  componentDidMount() {
        // ok: react-find-dom
    this.something.scrollIntoView();
  }

  render() {
    return (
      <div>
        <div ref={node => this.something = node} />
      </div>
    )
  }
}

react-find-dom.tsx

class TestComponent1 extends Component {
  componentDidMount() {
        // ruleid: react-find-dom
    findDOMNode(this).scrollIntoView();
  }

  render() {
    return <div />
  }
}

class OkComponent1 extends Component {
  componentDidMount() {
        // ok: react-find-dom
    this.node.scrollIntoView();
  }

  render() {
    return <div ref={node => this.node = node} />
  }
}

class TestComponent1 extends Component {
  componentDidMount() {
        // ruleid: react-find-dom
    ReactDOM.findDOMNode(this.refs.something).scrollIntoView();
  }

  render() {
    return (
      <div>
        <div ref='something' />
      </div>
    )
  }
}

class OkComponent2 extends Component {
  componentDidMount() {
        // ok: react-find-dom
    this.something.scrollIntoView();
  }

  render() {
    return (
      <div>
        <div ref={node => this.something = node} />
      </div>
    )
  }
}