React.createRef()报错‘Expected ref to be a function or a string’求助
Hey there! Let's break down why you're seeing this error and how to fix it.
问题根源
你用的React 16.3.2确实正式引入了React.createRef(),它返回的{ current: null }是完全符合官方规范的格式——但你的Card组件(大概率是第三方UI组件库的组件)还没适配React 16.3+的新ref API。
在React 16.3之前,只支持两种ref类型:
- 字符串ref(比如
ref="cardRef",现在已不推荐使用) - 回调函数ref(接收DOM元素/组件实例作为参数)
很多旧版本的第三方组件还没更新代码来识别新的ref对象格式,所以当你传递this.cardRef(一个对象)给Card的ref属性时,它就会抛出Expected ref to be a function or a string的错误。
解决方案
有两种简单的解决方式:
1. 改用回调函数ref(最稳妥,兼容所有组件版本)
你可以放弃createRef(),换成回调ref的写法,这是所有React版本都支持的方式:
export class MyComponent extends Component { constructor(props) { super(props); // 初始化ref存储变量 this.cardRef = null; // 定义设置ref的回调函数 this.setCardRef = (element) => { this.cardRef = element; }; } render() { return ( <div> ... <Card ref={this.setCardRef}> ... </Card> </div> ); } }
或者更简洁的内联箭头函数写法:
export class MyComponent extends Component { render() { return ( <div> ... <Card ref={(el) => this.cardRef = el}> ... </Card> </div> ); } }
之后你依然可以通过this.cardRef访问到组件实例,和createRef()的this.cardRef.current效果一致。
2. 升级Card组件到适配React 16.3+的版本
如果Card是某个UI库(比如Ant Design、Material-UI等)的组件,去检查它的版本更新日志,找到支持新ref API的版本并升级。升级后,React.createRef()的写法就能正常工作了。
额外说明
你的react-router-dom版本只要和React 16.3.2兼容(一般同大版本或者稍新一点都没问题),就不会影响这个问题——报错完全是Card组件不识别新ref对象导致的。
内容的提问来源于stack exchange,提问作者aditi

