0

I have a simple component that loads a 3rd party script that would inject some iframes to a div. I want to empty the div when the reset button is clicked. Since the content of the div is injected by a 3rd party script that is outside of react, the content does not clear when it rerenders. I have tried adding a key with current timestamp to the div but did not work. Any idea how to achieve this without using innterHTML = '' or empty DOM elements using vanilla javascript?

const App = () => {
  useEffect(() => {
    ... load a 3rd party script which then inject some iframes into #container
  }, []);

  const reset = () => {
    // how to empty the div #container
  };
 
  return (
    <div>
      <div id="container" />
      <button type="button" onClick={reset}>reset</button>
    </div>
  )
}

UPDATE: I figured this out. Setting key with timestamp worked. It is actually another issue causing it is not updating

user3908406
  • 1,416
  • 1
  • 18
  • 32
  • Does this answer your question? [Remove all child elements of a DOM node in JavaScript](https://stackoverflow.com/questions/3955229/remove-all-child-elements-of-a-dom-node-in-javascript) – Heretic Monkey Feb 16 '21 at 19:57
  • I know innerHTML = '' would work, but I'd like to know a react way instead of manipulating HTML directly – user3908406 Feb 16 '21 at 19:59
  • Check out this Example. This may help you https://www.codegrepper.com/code-examples/whatever/react+clear+an+input+useEffect – Mubo Feb 16 '21 at 20:15
  • That link only shows dynamically adding mousemove event handler – user3908406 Feb 16 '21 at 20:19
  • in your parent component, you can create a function which will do the required setState and then pass that function as props to the child component. then you can invoke it in onclick function . This will do a setState on the parent component – Belhadjer Samir Feb 16 '21 at 20:19
  • I tried this too, but still does not work, the iframes injected by the 3rd party script still there – user3908406 Feb 16 '21 at 20:22

2 Answers2

0

React should update component if state has changed.

You may try something like

const App = () => {
  useEffect(() => {
    ... load a 3rd party script which then inject some iframes into #container
  }, []);
  
  const [timeStamp, setTimeStamp] = useState(Date.now());


  const reset = () => {
    setTimeStamp(Date.now());
  };
 
  return (
    <div>
      <div id="container" data-timestamp={timeStamp} />
      <button type="button" onClick={reset}>reset</button>
    </div>
  )
}
Vlad
  • 459
  • 4
  • 8
  • For this case it does not. Because the content in the div is not managed by react, so the div remains the same – user3908406 Feb 16 '21 at 20:04
  • Hm, then, i suppose, you need directly manipulate the DOM content of this specific element... – Vlad Feb 16 '21 at 20:05
0

you can use your original timestamp idea. But to achieve that you have to turn your container to a Component, and pass your to key not to the div. Everytime a component's key changes it will remount that component:

const Container = () => <div id="container" ></div>

const App = () => {
  
  const [timeStamp, setTimeStamp] = useState(Date.now())


  const reset = () => setTimeStamp(Date.now())
 
  return (
    <div>
      <Container key={timeStamp} />
      <button type="button" onClick={reset}>reset</button>
    </div>
  )
}
buzatto
  • 9,704
  • 5
  • 24
  • 33