reactjsreact-refreact-portal

React portals and HTML injected through dangerouslySetInnerHTML


I have app where users can receives messages from admins. Admin create message in WYSIWYG editor on admin's panel, message is stored as html string in DB and then content of message is injected through dangerouslySetInnerHTML to component. HTML in messages is sanitized so there are only allowed tags and attributes ( no script tags, no event handler methods on tags, etc. ).

Everything was working, but now we have to add "form" feature to messages editor. Forms are created in separate tab on admins panel and then they can by attached to message. In message it's look like this.

<div data-form-id="12"/>

Empty div with form id. Now when message is displayed on user's app, I should handle this kind of div's and replaced them by expected form fetched from db ( forms are not stored as html, they are stored as specified json structure ).

First I thought about using React Portals, but read that they should be used to modify external HTML elements rather than those inside React app and it's bad practice to use them inside.

There is some "correct" way to achieve something like this or is it all a bad idea from the beginning?


Solution

  • should be used to modify external HTML elements rather than those inside React app

    It is not fully correct. React portal is used when you want to render element of react tree somewhere outside of react tree (meaning, into DOM that is not controlled by react). And DOM elements set with dangerouslySetInnerHTML are not controlled by React. I think your solution, given circumstances, is OK. You definitely should be careful and remove portals before you remove "message", so React would not try to render something into null, but otherwise it should work.