React中使用document.querySelectorAll获取DOM返回length为0如何解决
问题原因
你现在的写法执行时机不对:
- 你写的
const box = document.querySelectorAll('.boxes')代码是在模块加载阶段就直接执行的,这时候你的Easy组件还没有被渲染、挂载到页面的真实DOM树上,页面里根本不存在类名为boxes的元素,所以查询结果为空,长度为0。 - React的
render方法返回的是虚拟DOM,并不是直接生成真实DOM插入页面,只有组件完成挂载流程后,对应的真实DOM才会存在于文档中。
修正方案
如果你要查询组件内的DOM元素,要放在类组件的componentDidMount生命周期钩子中执行,这个钩子会在组件挂载到真实DOM后触发:
const boxes = { height: 220, width: 220, backgroundColor: 'red', borderRadius: '25%', }; const main = { display: 'grid', gridTemplateColumns: 'auto auto auto', gridGap: '20px', justifyContent: 'center', marginTop: '20px', }; class Easy extends React.Component { // 组件挂载完成后触发 componentDidMount() { const box = document.querySelectorAll('.boxes'); console.log(box.length); // 这里会输出3 } render() { return ( <div className="easy-game"> <div className="Easy-main" style={main}> <div style={boxes} className="boxes" /> <div style={boxes} className="boxes" /> <div style={boxes} className="boxes" /> </div> </div> ); } } export default Easy;
额外建议
React更推荐使用ref来获取内部DOM元素,避免直接全局查询DOM,更符合React的数据流逻辑,也能避免获取到其他组件内同名类的元素:
class Easy extends React.Component { constructor(props) { super(props); // 创建ref存储容器 this.boxRefs = []; } componentDidMount() { console.log(this.boxRefs.length); // 输出3 // 可以直接操作每个box的DOM元素 this.boxRefs.forEach(box => console.log(box)); } render() { return ( <div className="easy-game"> <div className="Easy-main" style={main}> <div style={boxes} className="boxes" ref={el => this.boxRefs.push(el)} /> <div style={boxes} className="boxes" ref={el => this.boxRefs.push(el)} /> <div style={boxes} className="boxes" ref={el => this.boxRefs.push(el)} /> </div> </div> ); } }
内容的提问来源于stack exchange,提问作者Hayder Ali
相关产品推荐
相关产品推荐

