.NET MVC中运行React代码渲染时遇报错:_registerComponent目标容器非DOM元素
嘿,这个错误我太熟了!本质就是React准备挂载组件的时候,找不到你指定的那个DOM容器元素,大概率是加载顺序、元素匹配或者.NET MVC视图渲染的问题,结合你的场景给你几个靠谱的排查和解决方向:
先搞定脚本加载顺序
很多人在.NET MVC里会把React相关脚本(包括你的reactscript.jsx)放在页面<head>里,这时候页面DOM还没完全渲染,React自然找不到目标容器。
最简单的解决办法:把所有React相关脚本移到</body>标签的前面,也就是页面最底部;或者给你的挂载代码套个DOM加载完成的监听事件,比如:document.addEventListener('DOMContentLoaded', function() { // 这里放你的ReactDOM.render代码 ReactDOM.render(<ItemDetailList data={yourData} />, document.getElementById('your-container-id')); });核对容器ID的每一个字符
仔细检查你的.NET MVC视图(.cshtml文件)里的容器元素ID,和React挂载代码里document.getElementById()的参数是不是完全一致——大小写、拼写、连字符都不能错!比如视图里是<div id="ItemDetailContainer"></div>,JS里就必须写document.getElementById('ItemDetailContainer'),差一个字母都不行。
另外还要确认这个容器元素确实存在于页面中,没有被条件渲染(比如@if判断)给隐藏或者删掉了。检查.NET MVC的视图渲染逻辑
如果你用了布局页(_Layout.cshtml),要确保你的视图内容(@RenderBody())的位置在脚本加载之前。比如脚本放在布局页的底部,而@RenderBody()在<body>中间,那没问题;但如果脚本在布局页的<head>里,那@RenderBody()的内容还没渲染,React肯定找不到容器。
要是用了部分视图(Partial View),也要确认包含容器的部分视图已经被正确渲染到主页面中了。排查JSX编译问题
你的reactscript.jsx文件有没有被正确编译成浏览器能识别的普通JavaScript?在.NET MVC里,你得确保有Babel这类工具处理JSX语法,不然浏览器会报语法错误,间接导致挂载失败。可以先打开浏览器控制台看看有没有其他错误,先把那些解决了,再回头看容器的问题。
举个完整的例子参考:
你的.cshtml视图里应该有这样的容器和脚本加载:
<div id="item-detail-container"></div> <!-- 页面底部加载React相关脚本 --> <script src="~/Scripts/react/react.min.js"></script> <script src="~/Scripts/react/react-dom.min.js"></script> <script src="~/Scripts/reactscript.js"></script>
你的reactscript.jsx里的代码要注意加key和DOM监听:
var ItemDetailList = React.createClass({ render: function () { var itemTable = this.props.data.map(function (itemarray) { // 记得给循环的元素加key属性,避免React警告 return ( <div key={itemarray.Id}> <h4>{itemarray.ServiceName}</h4> {/* 你的其他组件内容 */} </div> ); }); return <div>{itemTable}</div>; } }); // 等待DOM加载完成后再挂载组件 document.addEventListener('DOMContentLoaded', function() { // 从.NET MVC后端获取数据,比如用Model或者ViewBag var itemData = @Html.Raw(Json.Encode(Model.ItemList)); ReactDOM.render(<ItemDetailList data={itemData} />, document.getElementById('item-detail-container')); });
如果还是没解决,你可以打开浏览器开发者工具,在控制台里输入document.getElementById('你的容器ID'),看看返回的是不是null——如果是,那就是容器确实没被渲染到页面里,再回头检查你的视图逻辑就行。
内容的提问来源于stack exchange,提问作者sarath menon

