为何getElementById在Select TextField组件上无法正常工作?
问题描述
我有两个Material-UI的TextField组件,其中一个是带select属性的下拉选择型TextField,代码如下:
<TextField size="small" style = {{width: 700, marginTop: '1rem'}} type="text" multiline={schema.numberOfLines > 1} rows={schema.numberOfLines} required id="sampleTextField" name={schema.name} label={schema.display} variant="outlined" onChange={(event) => { handleDataChange(event.target.name, event.target.value); }}> </TextField> <TextField size="small" style = {{width: 300, marginTop: '1rem'}} required id="sampleSelect" name={schema.name} select label={schema.display} value={(reportDataObject[schema.name] !== undefined) ? reportDataObject[schema.name] : true } onChange={(event) => { handleDataChange(event.target.name, event.target.value); }}> <MenuItem key={true} value={true}>True</MenuItem> <MenuItem key={false} value={false}>False</MenuItem> </TextField>
执行以下代码时:
console.log(document.getElementById("sampleTextField").value); console.log(document.getElementById("sampleSelect").value);
普通文本型的sampleTextField能正常返回值“sample description”,但下拉选择型的sampleSelect却返回undefined。请问该问题的原因是什么?为何getElementById无法在Select组件上正常工作?
原因分析
核心问题出在Material-UI组件的DOM结构差异上:
- 普通文本型
TextField的根元素就是原生<input>标签,你设置的id直接绑定在这个<input>上,所以通过getElementById能直接拿到带有value属性的输入元素。 - 带
select属性的TextField,你设置的id会被应用到组件外层的容器或标签元素上,真正的原生<select>下拉元素是嵌套在组件内部的子节点。此时你通过getElementById("sampleSelect")获取到的是外层容器,这个容器本身没有value属性,自然返回undefined。
解决方案
推荐:通过React状态获取值
你已经在onChange事件里把选中值同步到了reportDataObject中,直接读取reportDataObject[schema.name]就能拿到当前选中值,这是React框架的标准做法,完全不需要依赖DOM结构,更稳定可靠。不推荐:定位内部原生select元素
如果一定要用原生DOM操作获取,需要主动定位到组件内部的原生<select>元素:const selectElement = document.getElementById("sampleSelect").querySelector("select"); console.log(selectElement.value);注意:这种方式依赖Material-UI组件的DOM结构,组件版本更新可能导致结构变化,存在维护风险,不建议在生产环境使用。
内容的提问来源于stack exchange,提问作者Jayesh Babu
相关产品推荐
相关产品推荐

