渲染时如何将Django数据传递给React组件?解决undefined问题
Django数据传递给React组件的标准实现方案(解决时序导致的全局变量undefined问题)
问题根源
你遇到的window.efestosData为undefined的问题,本质是代码执行时序不匹配:即使HTML中script标签顺序看起来是先解析数据再加载React JS,但如果React打包后的脚本是异步加载、或使用了模块类型(type="module"),React的初始化代码可能会在efestosData挂载到window之前执行,导致读取失败。
下面提供两种无需依赖DOMContentLoaded监听的标准实现方案:
方案一:通过初始化函数传递数据(推荐,无全局污染)
这种方式将React的初始化逻辑封装为可接收参数的函数,确保数据准备完成后再启动React应用,完全规避时序问题。
步骤1:修改React入口文件(index.js)
将初始化逻辑封装成公开的函数,接收数据作为参数:
import React from 'react'; import ReactDOM from 'react-dom/client'; import './index.css'; import EfestoComponent from './components/pulseHome'; import reportWebVitals from './reportWebVitals'; // 封装可接收数据的初始化函数 export function initReactApp(efestoObjects) { const root = ReactDOM.createRoot(document.getElementById('root')); root.render( <EfestoComponent objects={efestoObjects} /> ); reportWebVitals(); }
步骤2:修改Django模板中的HTML代码
先加载React的JS文件,解析数据后调用初始化函数传递数据:
<script id="efestos-data" type="application/json"> {{ efestos|safe }} </script> <!-- 先加载React打包后的脚本 --> <script src="{% static 'js/main.de0443a6.js' %}"></script> <script> // 解析数据 const efestosData = JSON.parse(document.getElementById('efestos-data').textContent); // 调用React初始化函数,传入数据 window.initReactApp(efestosData); </script>
方案二:通过DOM元素data属性传递数据
直接将序列化后的JSON数据嵌入React根元素的data属性中,React初始化时直接从DOM读取,无需全局变量。
步骤1:修改Django模板中的根元素
将数据添加到根元素的data属性:
<div id="root" data-efestos="{{ efestos|safe }}"></div>
步骤2:修改React入口文件(index.js)
从根元素的data属性读取并解析数据:
import React from 'react'; import ReactDOM from 'react-dom/client'; import './index.css'; import EfestoComponent from './components/pulseHome'; import reportWebVitals from './reportWebVitals'; // 获取根元素并解析数据 const rootElement = document.getElementById('root'); const efestoObjects = JSON.parse(rootElement.dataset.efestos); // 初始化React应用 const root = ReactDOM.createRoot(rootElement); root.render( <EfestoComponent objects={efestoObjects} /> ); reportWebVitals();
额外说明
两种方案都不需要依赖DOMContentLoaded监听,完全符合前后端数据传递的标准实践:
- 方案一避免了全局变量污染,适合复杂应用;
- 方案二实现更简洁,适合轻量场景。
内容的提问来源于stack exchange,提问作者Alejandro Veintimilla
相关产品推荐
相关产品推荐

