React中调用scrollIntoView()报TypeError: Cannot read property 'scrollIntoView' of null错误的问题求助
解决TypeError: Cannot read property 'scrollIntoView' of null的问题
看起来你遇到的问题核心在于执行滚动的时机不对,咱们一步步拆解来看:
问题根源
你现在把this.mapRef.current.scrollIntoView()放在了renderStoreCard方法里,这个方法是组件render流程的一部分——而React的render阶段只是生成虚拟DOM,此时真实DOM还没有完成挂载或更新,所以这时候this.mapRef.current可能还没指向实际的DOM元素,哪怕你之前console.log看到过它有值,那也是在之前的渲染周期里的结果,当前渲染时它可能还是null。
另外还有个逻辑问题:你现在每次渲染商店卡片都会触发滚动,这显然不是你想要的,你应该是想在用户点击「Show on the map」按钮的时候才触发滚动到地图的操作对吧?
修复方案
把滚动逻辑移到按钮的onClick回调里,同时加上安全检查确保元素存在:
export class FinderComponent extends PureComponent { constructor(props) { super(props); this.mapRef = React.createRef(); } renderMap() { return <div block="StoreFinder" ref={this.mapRef}></div>; } renderStoreCard(store) { // 这里移除scrollIntoView的调用 return ( <div block="StoreFinder" elem="Store" key={store_name.replace(/\s/g, "")} mods={{ isActive: store_name === selectedStoreName }} > {this.renderStoreCardContent(store)} <button block="Button" mods={{ likeLink: true }} onClick={() => { // 把滚动逻辑移到这里,先检查元素是否存在 if (this.mapRef.current) { this.mapRef.current.scrollIntoView({ behavior: "smooth" }); } changeStore(store); }} > {__("Show on the map")} </button> </div> ); } }
额外说明
- 永远在调用DOM元素的方法前做存在性检查,哪怕你确定ref已经绑定,也能避免组件卸载时或异常情况下的报错。
- React的ref在组件的
commit阶段才会被赋值为真实DOM元素,所以不要在render阶段直接操作ref指向的DOM,尽量把DOM操作放在事件回调、componentDidMount这类生命周期方法中。
内容的提问来源于stack exchange,提问作者Jānis Kļaviņš
相关产品推荐
相关产品推荐

