React中draggable()函数使用及ES6类转换报错问题咨询
Hey there! Let's tackle this issue you're facing. When you switched from React's createClass to ES6 classes, your draggable() call started throwing that "is not a function" error—even though it worked perfectly before. Let's break down why this happens and how to fix it.
First, Why the Error?
The core issue usually boils down to one of a few things:
- You're using
ReactDOM.findDOMNode()(the ES6 class equivalent ofthis.getDOMNode()) but either jQuery UI isn't properly attached to your jQuery instance, or you're not targeting the right DOM element. findDOMNode()has edge cases (like if your component returns multiple root elements) that can returnnull, making the jQuery wrapper useless.- You might have jQuery and jQuery UI loaded in the wrong order, or multiple conflicting jQuery instances.
Recommended Solution: Use React Refs (Instead of findDOMNode)
findDOMNode() is deprecated in React's Strict Mode and not recommended for modern code. Refs are a cleaner, safer way to grab DOM nodes directly. Here's how to implement it:
import React from 'react'; import ReactDOM from 'react-dom'; class DraggableBox extends React.Component { constructor(props) { super(props); // Create a ref to hold the DOM element this.draggableElement = React.createRef(); } componentDidMount() { // Apply jQuery UI draggable to the ref's current element $(this.draggableElement.current).draggable(); } componentWillUnmount() { // Clean up the draggable instance to avoid memory leaks $(this.draggableElement.current).draggable('destroy'); } render() { // Attach the ref to the element you want to make draggable return ( <div ref={this.draggableElement} style={{ width: '200px', height: '200px', background: 'lightblue' }}> Drag me around! </div> ); } }
Why This Works Better:
- Refs directly reference the DOM element you care about, no guesswork.
- No issues with
findDOMNode()returningnullif your component structure changes. - It's aligned with React's best practices and won't trigger warnings in Strict Mode.
If You Must Use findDOMNode()
If you need to stick with findDOMNode() for some reason, make sure you validate the node exists before calling draggable():
componentDidMount() { const domNode = ReactDOM.findDOMNode(this); // Check if the node exists before proceeding if (domNode) { $(domNode).draggable(); } }
But again, this isn't the long-term solution—refs are the way to go.
Quick Troubleshooting Checks
If you still get the error after trying the above:
- Check jQuery/UI load order: Always load jQuery first, then jQuery UI. If you load UI first, it can't attach
draggable()to the jQuery object. Example:<!-- Correct order --> <script src="path/to/jquery.min.js"></script> <script src="path/to/jquery-ui.min.js"></script> - Verify no duplicate jQuery instances: If your page loads jQuery more than once, the
$variable might point to an instance that doesn't have jQuery UI attached. Runconsole.log($.fn.draggable)in your browser console—if it returnsundefined, jQuery UI isn't loaded correctly. - Ensure your component has a single root element:
findDOMNode(this)returns the root DOM element of your component. If yourrender()returns multiple un-wrapped elements, it'll returnnull, breaking the jQuery call. Wrap everything in a single<div>or fragment.
内容的提问来源于stack exchange,提问作者Areeb Khan




