Package: django-byo-react
Django BYO ReactA minimal template tag which creates a div element for React to bind to and a Djangojson_scriptwhich can be used to pass values from Django into the root React element as props. This library remains unopinionated about the React code by design since there are so many ways to create and maintain React apps.UsageInstall the app insettings.pyINSTALLED_APPS=["django_byo_react",...]In the template that you want to install a react app load the tag and use it with the givenkwargs. You can add extra props to the root react component by addingkwargsto the tag element. As long as is json serializable it can be included in the props. This library will give the json script a random uuid and add that as a data attributedata-script-idto the react app div. This can be used to access the data using javascript.Example using element idIf the react app is a one off embed we can use thedivid to connect the backend to the frontend. In the following example we've used a simple string idreact-app-id.Django{%loadbyo_react%}{%byo_reactid="react-app-id"className="w-100"showActive=True%}{%comment%}showActive is an extra keyword argument rendered in a html script tag{%endcomment%}This will render with the following HTML:<scriptid="<script-random-uuid>"type="application/json">{"showActive":true}</script><divid="react-app-id"data-script-id="<script-random-uuid>"class="w-100"></div>Javascript/TypescriptThe JS/TS side is left to the user as there are many ways in which one can create a react app. This leaves the most flexibility to integrate existing react apps and frameworks into a django page.Here is a typical example for a very basic app using the div element idreact-app-idto connect the root component from the backend render.importReact,{FC}from"react";importReactDOMfrom'react-dom/client';// Example root component for a react appconstApp:FC=(props)=><div{...props}></div>constelementId="react-app-id"constcontainer=document.getElementById(elementId)if(!container)thrownewError(`Can't find element with id${elementId}`);// Extract props from the django json_script tagconstjsonContent=document.getElementById(container.dataset?.scriptId)?.textContent;if(!jsonContent)thrownewError("No associated script found");// props will be a dictionary containing the tag kwargs// eg: The props constant will be an object with { showActive: true }constprops=JSON.parse(jsonContent);constroot=ReactDOM.createRoot(container)root.render(<App{...props}/>);Example using component nameThere is an optionalcomponent_nameargument in the djangobyo_reacttemplate tag. This is intended for adding the react app root component name directly to the div data attribute so it can be used from the frontend. With the component name we can embed the same react app several times. This might be useful for a react app that needs to be used in several different elements on the same page such as form fields. Here's an example of how we might do that.Django{%loadbyo_react%}{%byo_reactcomponent_name="App"className="w-100"showActive=True%}This will render with the following HTML:<scriptid="<script-random-uuid>"type="application/json">{"showActive":true}</script><divid="<div-random-uuid>"data-script-id="<script-random-uuid>"data-component-name="App"class="w-100"></div>Javascript/TypescriptimportReact,{FC}from"react";importReactDOMfrom'react-dom/client';// Example root component for a react appconstApp:FC=(props)=><div{...props}></div>// Get all elements with data attribute `component-name` as "App"document.querySelectorAll("[data-component-name='App']")).forEach(container=>{// Extract props from the django json_script tagconstjsonContent=document.getElementById(container.dataset?.scriptId)?.textContent;if(!jsonContent)thrownewError("No associated script found");// props will be a dictionary containing the tag kwargs// eg: The props constant will be an object with { showActive: true }constprops=JSON.parse(jsonContent);constroot=ReactDOM.createRoot(container)root.render(<App{...props}/>);})