Home > Software design >  React - append DOM infinitely without max depth / infinite loop errors?
React - append DOM infinitely without max depth / infinite loop errors?

Time:01-24

This maybe be counter to the essence of React, but... can I update the DOM infinitely?

i.e. I want to run something like this until I kill the app. Adding a STOP button would be nice, but I can CTRL C in the console.

x=1;
while(x > 0){
  // append DOM with `<div>${x}</div>`
  x =1;
}

I'm using useRef for the DOM container and have tried putting the logic in a useEffect hook but React doesn't like open-ended updates.

CodePudding user response:

I'm very intrigued as to your use case, it would be good to know more about it, as the request is an odd one, but I like the challenge so here I go.

React has infinite loop detection but you could do this by making sure that a DOM element is added only after each the previous one has been committed to the DOM.

import { useState, useLayoutEffect } from "react";

export default function InfiniteDivAppender() {
  const [divCount, setDivCount] = useState(1);
  const [pause, setPause] = useState(false);

  useLayoutEffect(() => {
    if (pause) return;
    setImmediate(() => setDivCount((prev) => prev   1));
  }, [divCount, pause]);

  return (
    <>
      <button onClick={() => setPause((prev) => !prev)}>
        {pause ? "Resume" : "Pause"}
      </button>
      {[...Array(divCount).keys()].map((n, index) => (
        <div key={index}>{index}</div>
      ))}
    </>
  );
}


Note this is still an insane amount of browser ops and you'll likely need to wait for a few seconds for the tab to catch up, but it does print eventually and it also does not trigger the loop detection because I'm using setImmediate alongside useLayoutEffect (note: not useEffect).

Note ctrl c on the console probably won't save you from a crashed browser tab -- which it will crash eventually with this because you cant have infinite nodes on a web page.

CodePudding user response:

I accomplished this with an infinite loop useEffect. It looks like it gives you an error in the console about maximum depth, but it seems to still run?

Edit gallant-rain-y7925k

import "./styles.css";
import {useState, useEffect} from "react"

export default function App() {
  const [array, setArray] = useState([])
  useEffect(() => {
    setArray([...array, "hi"])
  }, [array])
  return (
    <div className="App">
      {array.map((_, i) => <h1 key={i}>#{i}</h1>)}
    </div>
  );
}
  • Related