You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

React无状态组件中createRef失效,调用focus报空值错误

问题分析与解决方案

你遇到的这个'Cannot read property "focus" of null'错误,核心原因是在函数组件里误用了createRef,而没有使用React为函数组件专门设计的useRef Hook,和父组件的Redux connect包装没有关系。

为什么会出错?

createRef是为类组件设计的,它的特性是每次组件重新渲染时都会生成一个全新的引用对象。而你的Card是函数组件,每次状态变化(比如切换编辑模式)都会重新执行整个组件函数,这时候inputText = createRef()会创建新的ref,导致当你调用inputText.current.focus()时,这个新的ref还没关联到真实的DOM元素,自然就是null。

而useRef Hook会在组件的整个生命周期内保持同一个引用对象,不管组件渲染多少次,它指向的都是同一个DOM节点(当ref被挂载后)。

修复后的代码

只需要把createRef替换成useRef,同时记得从React导入useRef:

import React, { useRef } from 'react'; // 替换原来的createRef为useRef
import './Card.scss';
const Card = ({isEditing, item, onBlur, onChange}) => {
  const inputText = useRef(null); // 用useRef初始化,默认值设为null
  const editing = (editMode) => {
    if (editMode) {
      // 加可选链操作符,避免DOM未挂载时调用focus报错
      inputText.current?.focus();
    }
    return e => {
      e.stopPropagation();
      isEditing(item, editMode);
    };
  }
  const update = () => {
    return e => {
      onChange(item.id, e.target.value);
    }
  }
  return (
    <div className="card">
      <img className="card-image" src="https://picsum.photos/200/200" alt="no image display" />
      <div className="card-body">
        {item.edited ? (
          <div>
            <input type="text" ref={inputText} onClick={e => e.stopPropagation()} value={item.name} onBlur={editing(false)} onChange={update()} />
          </div>
        ) : (
          <h3 className="card-title" onClick={editing(true)}>
            {item.name}
          </h3>
        )}
      </div>
    </div>
  );
}
export default Card;

额外优化提示

  • 我在调用focus时加了可选链操作符?.,这样即使inputText.current还是null(比如DOM还没来得及挂载),也不会抛出错误,代码更健壮。
  • 你的update和editing函数每次渲染都会创建新的事件处理函数,后续可以用useCallback来优化性能,不过这不是导致当前错误的原因,属于可选优化。

内容的提问来源于stack exchange,提问作者Joseph Williams

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.27 04:26:34