Here’s a page where I am importing my vanilla JS file:
import React from 'react';
import '../js/accountAdmin.js';
const Home = () => {
return (
<div className="app">
<section className="side-bar">
<nav>
<p>My Page</p>
</nav>
</section>
<section className="main">
<h1>My Page</h1>
<span>Click on a cell to edit:</span>
<div className="accountsTableDiv"></div>
<div className="addAccount"></div>
<div className="feedbackMessages"></div>
<div className="bottom-section">
<p className="info">
Frontend for MyPage.
</p>
</div>
</section>
</div>
);
};
export default Home;
Here’s the JS file:
let tblBody;
const url = "http://localhost:8080/api/v1/accounts";
//wait until the page loads.
window.onload = async function() {
let feedbackMessage = document.querySelector(".feedbackMessages");
let accountsTableDiv = document.querySelector(".accountsTableDiv");
let accountAddDiv = document.querySelector(".addAccount");
let table = document.createElement('table');
console.log(feedbackMessage); //null on refresh, works fine on hard reload
console.log(accountsTableDiv); //null on refresh, works fine on hard reload
console.log(accountAddDiv); //null on refresh, works fine on hard reload
console.log(table);
tblBody = document.createElement('tbody');
console.log(tblBody);
console.log("onload() ended");
};
The document.querySelector()
statements are returning null on refresh, but they work as expected on hard reload. I’m guessing this has something to do with React’s virtual DOM, but I’m not sure what to do about it. What should I do? What do I need to understand about React when it comes to using vanilla JS?
2
Answers
It’s not advised to manipulate DOM elements directly using JavaScript code or jQuery because they are managed by React. So if you want to access an element you could use a ref to the DOM node as it is explained here.
However, in some cases, you can avoid accessing DOM elements by combining useState, useEffect and Conditional Rendering:
The most common advice you are going to hear is not to manipulate DOM manually in React app (and based on your code snippets your vanilla JS code can easily be refactored into standard React code). However, according to the React documentation, manual DOM manipulation can safely be used as long as there are no conflicting changes.
https://react.dev/learn/manipulating-the-dom-with-refs#best-practices-for-dom-manipulation-with-refs
While I was unable to reproduce your specific issue, I suspect there may be a race condition between
window.onload
and React rendering your component. To guarantee the right execution order, I can suggest the following approach:<div>
is already present in DOM)