React components can also perform side effects instead of rendering something to the screen. For example, insert a script to the page or insert a listener to some events. In that case, I don't have to return anything in the render function.
The below example shows how to use a component to insert a script into the page. I can use it as a reusable utility component to insert different scripts into the page.
import { useCallback, useEffect } from "react"
interface ScriptProps {
resourceType: 'javascript' | 'css'
src: string
id: string
}
export const ScriptManager = (props: ScriptProps): null => {
const insertScript = useCallback(() => {
let link: HTMLScriptElement | HTMLLinkElement
if (props.resourceType === 'javascript') {
link = document.createElement('script')
link.type = 'text/javascript'
link.setAttribute('src', props.src)
} else {
link = document.createElement('link')
}
link.id = props.id
document.head.appendChild(link)
}, [props.id, props.resourceType, props.src])
useEffect(() => {
insertScript()
}, [insertScript])
return null;
}
The above component can insert a Javascript tag or a CSS link into the page header. I use the useEffect
hook to avoid any duplicate inserts.
Ideally, I should check to see if the resource exists before inserting it.
It is crucial to return null to make this component valid as a React component. Ideally, a React component must return a JSX
element, at least an empty fragment.
But I don't need that. If I don't return at least null, it will throw the "Its return type 'void' is not a valid JSX element" error when I use this element.
Here is how to use my component to insert Jquery into the page.
import { ScriptManager } from "./script_manager";
const App = () => {
return <>
<ScriptManager
resourceType="javascript"
src="https://code.jquery.com/jquery-3.6.2.min.js"
id="jquery"
/>
</>
}
export default App;