React 中如何在 componentDidMount 生命周期中为 button 设置聚焦
问题原因
- 最常见的诱因是
this.props.data.active在组件首次挂载时还未拿到预期值1:如果这个data是父组件通过异步请求获取后传递的,组件第一次触发componentDidMount时,父组件的异步请求还没返回,data.active还不是1,条件判断不通过,聚焦逻辑自然不会执行。等到父组件异步数据更新传递到子组件时,componentDidMount已经触发完毕不会再执行,所以你把逻辑放到componentDidUpdate里能生效,就是因为此时props已经更新为正确值。 - 另外还有个隐性问题:你没有对ref是否存在做兜底判断,如果按钮存在条件渲染逻辑、或者ref赋值失败的场景下,直接调用
this.button.focus()会抛出空引用错误。
修复方案
把聚焦逻辑抽为公共方法,同时在componentDidMount和componentDidUpdate中调用,既覆盖首次挂载场景,也覆盖props/state更新后的场景,同时加ref和属性存在性判断:
class XY extends Component { constructor(props) { super(props) this.state = { open: false } } // 抽离公共的聚焦判断逻辑 tryFocusButton = () => { // 加可选链避免data为undefined时报错,加ref存在判断避免空引用错误 if(this.state.open === false && this.props.data?.active === 1 && this.button) { this.button.focus() } } componentDidMount() { this.tryFocusButton() } componentDidUpdate(prevProps, prevState) { // 可选优化:只有相关依赖变化时才执行判断,减少不必要的逻辑执行 if(prevProps.data?.active !== this.props.data?.active || prevState.open !== this.state.open) { this.tryFocusButton() } } render() { return ( <div> <button ref={c => (this.button = c)}> button </button> </div> ) } }
内容的提问来源于stack exchange,提问作者Deathlex
相关产品推荐
相关产品推荐

