Context Provider for injecting a ReactNode into the DOM.
Ability to remove (uninject) or purge nodes from the page via. an id parameter.
Example
_app.tsx
import { InjectProvider } from'react-node-inject';constApp= () => {return (// This is the level at which injectables will be appended to the DOM. <InjectProvider> // The rest of the app. // May contain <MyReactComponent /> from below or something similar. </InjectProvider> );}exportdefault App;
MyReactComponent.tsx
import { useInject } from'react-node-inject';constMyReactComponent= () => { { inject } =useInject();consthandleClick= () => {inject(// An example of a modal with TailwindCSS// You can also inject a custom <Modal /> component you have, etc. <divclassName='absolute min-h-screen flex items-center justify-center'> <divclassName='border bg-white shadow px-8 py-4'> This modal is injected when the button is clicked! </div> </div> ); }return ( <buttononClick={handleClick}>Click me</button> )}exportdefault MyReactComponent;
The Problem We're Solving
Instead of loading a modal with an empty state, you can "inject" components on the fly into the DOM. This way, the client isn't seeing any content they shouldn't to begin with and you can have multiple instances of modals, toasts, etc.
In other words, you'll never do this again:
BadModal.tsx
interfaceIBadModalProps { message:string;}// This is an example of what bad code looks like.// Don't do this!constBadModal= ({ message }:IBadModalProps) => {// Preventing the modal from showing if the message doesn't exist.if(message ==='') {returnnull; }return (// The modal when a message exists. )}exportdefault BadModal;
BadForm.tsx
import { Fragment } from'react';// This is an example of what bad code looks like.// Don't do this!constBadForm= () => {const [message,setMessage] =useState('');consthandleClick= () => {setMessage('You clicked the button!') }return ( <Fragment> {/* We're trying to avoid this: */} <BadModalmessage={message} /> <buttononClick={handleClick}>Submit</button> </Fragment> )}exportdefault BadForm;
Instead, you can start doing this:
GoodModal.tsx
interfaceIGoodModalProps { message:string;}constGoodModal= ({ message }:IGoodModalProps) => {return (// The modal - the message is guarenteed to be here. )}exportdefault GoodModal;
GoodForm.tsx
import { inject } from'react-node-inject'constGoodForm= () => {consthandleClick= () => {// An example of when you can inject a modal.inject(<GoodModalmessage='You clicked the button!' />); }return ( <buttononClick={handleClick}>Submit</button> )}exportdefault GoodForm;
Inject Context
interfaceIInjectContext {// Inject a ReactNode into the DOM with an optional idinject: (node:ReactNode, id?:string) =>void;// If an injected ReactNode has an id, remove it from the DOM.uninject: (id:string) =>void;// Purge all injected ReactNode components from the DOM.purge: () =>void;// An array of injectables (contains id: string and node: ReactNode properties) injected:Injectable[];}
Contributing
At the moment, this repository is maintained by a student at Iowa State University. If you'd like to contribute, please fork this repository, make your changes, and then send in a pull request. Please respect the current .prettierrc configuration - thank you!