越是漂亮的女人越会骗人,react 19 也是。
大家好,我是芋仔,距离 react 19 发布已经过去一个月了,移除了一些废弃语法,其中,让开发体验拉满的,应该是 ref 作为一个常驻参数的改动了。
看到更新日志中前面几条,几乎是无感,而看到这一条,可算是不需要 forwardRef 这个玩意包裹了,可谓是方便很多。当场决定升级!
但是玫瑰都带刺。
可以看如下代码:
import { useRef, useEffect } from 'react'
const SomeComponent = ({
style,
...props
}) => {
const divRef = useRef(null)
useEffect(() => {
// do something with divRef.current
// divRef.current 是 null
}, [])
return (
<div style={style} ref={divRef} {...props} />
)
}
const App = () => {
const myRef = useRef(null)
return (
<SomeComponent ref={myRef} style={{}}/>
)
}
以往这么写是没有问题的,但是当 ref 作为一个参数之后,...props
中就可能会包含一个 ref 参数(如果外面组件恰好也传递了ref参数),从而覆盖 divRef,从而导致 divRef 不会被赋值。
知道原因后,要做调整其实也非常简单
//<div style={style} ref={divRef} {...props} />
<div style={style} {...props} ref={divRef} />
调整参数位置即可。
就这?
说到这里,肯定有人要划走了,就这,这就栽跟头了?多大点事。
如果仅仅是这样,我也不会做记录了。
实际这些 bug,发生在我依赖的组件库中。
而组件库中的代码,是已经经过了 babel 编译的代码,可以感受下上述代码经过 jsx 编译后的结果:
import { useRef, useEffect } from 'react';
import { jsx as _jsx } from "react/jsx-runtime";
var SomeComponent = function SomeComponent(_ref) {
var style = _ref.style,
props = _objectWithoutProperties(_ref, _excluded);
var divRef = useRef(null);
useEffect(function () {
// do something with divRef.current
// divRef.current 是 null
}, []);
return /*#__PURE__*/_jsx("div", _objectSpread({
style: style,
ref: divRef
}, props));
};
从代码上,是不太好推断出来这是 ref 位置写法带来的问题。甚至会怀疑,自己学的 jsx 的编译是不是正确的了。
再来看看正确写法编译后的结果:
var OkComponent = function OkComponent(_ref2) {
var style = _ref2.style,
props = _objectWithoutProperties(_ref2, _excluded2);
var divRef = useRef(null);
useEffect(function () {
// do something with divRef.current
// divRef.current 是 可以获取到的
}, []);
return /*#__PURE__*/_jsx("div", _objectSpread(_objectSpread({
style: style
}, props), {}, {
ref: divRef
}));
};
可以说是相当隐晦了。
不过还好,也算是吃到螃蟹了,其他地方暂时还没有发现比较隐晦的 bug,这篇文章也希望能帮助大家少走一些弯路。各组件库作者也可以稍稍留意喽。
最后,别忘了关注我公众号:程序员芋仔。每周(也可能每月)更新一篇程序员大佬分析。
后互联网时代,我也组建了一个前端抱团取暖群,欢迎加我微信来撩:mxb151,加群备注简单的自我介绍和加群哦。