Home > Software engineering >  How to bind a react hook to an element created by jquery function
How to bind a react hook to an element created by jquery function

Time:02-05

I'm working with a project written in jquery and I want to integrate this code in my react project. I'm trying to send a query to my graphql server by clicking a button.

There is a JQ function that creates multiple elements like this:

 canvas.append($(`<div ><img  src="${elem.artworkUrl600}" height="150px"><div ><div  id="${elem.trackId}">${elem.trackName}</div><h6>by:${elem.artistName}</h6><h6>keywords:</h6><p>${elem.genres}</p><div ><button value="${elem.feedUrl}" ><a target="_blank" href="${elem.trackViewUrl}">Info link</a></i></button><div ><i id="like" ></div></div></div><hr>`)
    );

My goal is to connect a function "onClick()" to all buttons inside these created elements. For that I'm trying to define a function that would query all elements by id and connect it to a function with a hook to my graphql server:

function connectFunctionalityToLike(){
  $("#like").on("click", function(){ Like(this); });
}

function Like(x){
  console.log("clicked");

  const { loading, error, data } = useQuery(ME_QUERY);
    if (loading) return 'Loading...';
    if (error) return `Error! ${error.message}`;
  
    console.log(data);
  
}

My function Like() does not really work because I'm missing in understanding how elements in react actually work all together with jquery. I cannot rewrite code in JQuery. I just want to integrate this existing code. Is there any way around connecting react hooks to created elements by id?

Is there

CodePudding user response:

As Andy says in his comment: "You shouldn't be mixing jQuery and React." - But, we've all be in spots where we are given no choice. If you have no choice but to use jQuery along side React, the code in the following example may be helpful.

Example is slightly different (no canvas, etc), but you should be able to see what you need.

This example goes beyond your question and anticipates the next - "How can I access and use the data from that [card, div, section, etc] that was added by jQuery?"

Here is a working StackBlitz EDIT - fixed link

Please see the comments in code:

// jQuery Addition - happens outside the React App
$('body').append(
  $(`<div ><img  src="${elem.artworkUrl600}" height="10px"><div ><div  id="${elem.trackId}">${elem.trackName}</div><h6>by:${elem.artistName}</h6><h6>keywords:</h6><p>${elem.genres}</p><div ><button value="${elem.feedUrl}" ><a target="_blank" href="${elem.trackViewUrl}">Info link</a></i></button><div ><i id="like" ></div></div></div><hr>`)
);

export default function App() {
  // state to hold the like data
  const [likes, setLikes] = useState([]);
  // create reference to the jquery element of importance
  // This ref will reference a jQuery object in .current
  const ref = useRef($('.elseTitle'));
  // Like function
  function Like(x) {
    // ref.current is a jQuery object so use .text() method to retrieve textContent
    console.log(ref.current.text(), 'hit Like function');
    setLikes([...likes, ' :: '   ref.current.text()]);
  }
  // This is where you put
  useEffect(() => {
    // Add event listener and react
    $('#like').on('click', function () {
      Like(this);
    });
    // Remove event listener
    return () => $('#like').off('click');
  });
  return (
    <div>
      <h1>Likes!</h1>
      <p>{likes}</p>
    </div>
  );
}

CodePudding user response:

You should create a React component wrapper for the JQuery function.

You will have to manage the React lifecycle manually - by calling the JQuery function in a useEffect() callback and taking care to remove the DOM elements in the cleanup:

function ReactWrapper() {
  const { loading, error, data } = useQuery(ME_QUERY);
  const [ data, setData ] = React.useState();
  React.useEffect(() => {
    jqueryFn();
    $('#like').on('click', function(){ setData('from click') });
    return () => {
       /* code that removes the DOM elements created by jqueryFn() */
    };
  }, []);

  if (loading) return 'Loading...';
  if (error) return `Error! ${error.message}`;

  return <div>{data}</div>;
}

Then, in this React component, will be allowed to use hooks.

Also, if your JQuery function is so simple, you are probably much better off with rewriting it in React.

  • Related