Home > Enterprise >  If I am manipulating the DOM with vanilla JS... can I make one of those items a React component?
If I am manipulating the DOM with vanilla JS... can I make one of those items a React component?

Time:05-20

I've got an applet right now that builds a table of TODOs using vanilla JS.

Is it possible to add a React component button to one of those TODOs? Specifically trying to update the button, but React does not like you manipulating the DOM manually... so is this even doable? I thought it was possible to have React alongside other code. I've seen static examples such as this in their docs, but nothing dynamic like this.

e.g.

document.addEventListener('DOMContentLoaded', function () {
    fetch('/getTodos')
    .then(response => response.json())
    .then(data => {
        console.log(data)
        loadTodos(data)
    })
})

function loadTodos(data) {

    const table = document.getElementById("todos-list")

    if (data.length === 0) { return table.innerHTML = "<tr><td>Nothing to do!</td></tr>" }

    let content = ""

    data.forEach( ({id,todo,dueDate}) => {
        content  = `<tr><td>${todo}</td></tr>`
        content  = `<tr><td>${new Date(dueDate).toLocaleString()}</td></tr>`
        content  = `<tr><td><button  data-id=${id} onclick='deleteMe(${id})'>Delete</button></td></tr>`
    })

    table.innerHTML = content

}

CodePudding user response:

You can dynamically insert a React component into an existing container easily enough:

setTimeout(() => {
  // simulating async api call
  const table = document.getElementById("todos-list");
  table.innerHTML = `
  <tbody>
  <tr><td ></td><td>another td</td></tr>
  <tr><td>another row</td></tr>
  </tbody>
  `;
  ReactDOM.render(<App />, document.querySelector('.target'));
}, 500);


const App = () => {
    return <span><button>Dynamic Component</button></span>;
};
<script crossorigin src="https://unpkg.com/react@16/umd/react.development.js"></script>
<script crossorigin src="https://unpkg.com/react-dom@16/umd/react-dom.development.js"></script>
<table id='todos-list'></div>

But other than populating container(s), there's no sane way to turn existing elements into React elements. Your <button data-id=${id} onclick='deleteMe(${id})'>Delete</button> can't be turned into a component (though with some ugly code you could have a separate React component that adds a click listener to it... but don't do that). In React, you should always start with a container or few that you then insert your app's components into.

  • Related