React Ref 其实是这样的
ref 的由来在典型的 React 数据流中 , props 是父组件与子组件交互的唯一方式 。 要修改一个子组件 , 你需要使用新的 props 来重新渲染它 。 但是 , 在某些情况下 , 你需要在典型数据流之外强制修改子组件/元素 。
适合使用 refs 的情况:
- 管理焦点 , 文本选择或媒体播放 。
- 触发强制动画 。
- 集成第三方 DOM 库 。
ref 通过字符获取:
// string refclass MyComponent extends React.Component {componentDidMount() {this.refs.myRef.focus();}render() {return ;}}ref 通过回调函数获取:// callback refclass MyComponent extends React.Component {componentDidMount() {this.myRef.focus();}render() {return {this.myRef = ele;}} />;}}在 v16.3 中 , 经 0017-new-create-ref 提案引入了新的 API:React.createRef 。ref 通过 React.createRef 获取:
// React.createRefclass MyComponent extends React.Component {constructor(props) {super(props);this.myRef = React.createRef();}componentDidMount() {this.myRef.current.focus();}render() {return ;}}当然还有最近react大力推崇的 hooks:useReffunction MyComponent() {const myRef = useRef(null);const onButtonClick = () => {// `current` 指向已挂载到 DOM 上的文本输入元素myRef.current.focus();};return (<>聚焦>);}将被移除的 string ref首先来具体说说 string ref , string ref 就已被诟病已久 , React 官方文档中如此声明:"如果你目前还在使用 this.refs.textInput 这种方式访问 refs, 我们建议用回调函数或 createRef API 的方式代替 。 " , 为何如此糟糕?最初由 React 作者之一的 dan abramov 。 发布于 , (该网站需要梯子) 。 吐槽内容主要有以下几点:
- string ref 不可组合 。例如一个第三方库的父组件已经给子组件传递了 ref , 那么我们就无法在在子组件上添加 ref 了 。另一方面 , 回调引用没有一个所有者 , 因此您可以随时编写它们 。 例如:
/** string ref **/class Parent extends React.Component {componentDidMount() {// 可获取到 this.refs.childRefconsole.log(this.refs);}render() {const { children } = this.props;return React.cloneElement(children, {ref: 'childRef',});}}class App extends React.Component {componentDidMount() {// this.refs.child 无法获取到console.log(this.refs);}render() {return ( );}}- string ref 的所有者由当前执行的组件确定 。这意味着使用通用的“渲染回调”模式(例如react) , 错误的组件将拥有引用(它将最终在react上而不是您的组件定义renderRow) 。
class MyComponent extends Component {renderRow = (index) => {// string ref 会挂载在 DataTable this 上return ;// callback ref 会挂载在 MyComponent this 上return this['input-' + index] = input} />;}render() {return }}- string ref 不适用于Flow之类的静态分析 。Flow不能猜测框架可以使字符串ref“出现”在react上的神奇效果 , 以及它的类型(可能有所不同) 。回调引用比静态分析更友好 。
- string ref 强制React跟踪当前正在执行的组件 。这是有问题的 , 因为它使react模块处于有状态 , 并在捆绑中复制react模块时导致奇怪的错误 。 在 reconciliation 阶段 , React Element 创建和更新的过程中 , ref 会被封装为一个闭包函数 , 等待 commit 阶段被执行 , 这会对 React 的性能产生一些影响 。
在调和子节点得过程中 , 会对 string ref 进行处理 , 把他转换成一个方法 , 这个方法主要做的事情就是设置 instance.refs[stringRef] = element , 相当于把他转换成了function ref
对于更新得过程中string ref是否变化需要对比得是 current.ref._stringRef , 这里记录了上一次渲染得时候如果使用得是string ref他的值是什么
owner是在调用createElement的时候获取的 , 通过ReactCurrentOwner.current获取 , 这个值在更新一个组件前会被设置 , 比如更新ClassComponent的时候 , 调用render方法之前会设置 , 然后调用render的时候就可以获取对应的owner了 。
坚挺的 callback refReact 将在组件挂载时 , 会调用 ref 回调函数并传入 DOM 元素 , 当卸载时调用它并传入 null 。 在 componentDidMount 或 componentDidUpdate 触发前 , React 会保证 refs 一定是最新的 。
- 曝光|OPPO新机曝光,配置强悍颜值动人,“三金影后”为其代言
- 三星|高通骁龙875即将登场,三星Exynos 1080成其唯一对手
- 部署模式|5G toB大戏拉开帷幕,公网专用正当其时
- 小米|华为成俄罗斯线上销售最受欢迎品牌!小米紧随其后
- 中企|这和不要脸有何区别限制中企发展,还想要求中方给其“开后门”
- 欺诈和滥用|美国最高法院审理黑客法及其限制的案件
- 经济损失及|爱奇艺起诉马上玩App分时出租其平台VIP帐号,获赔300万元
- 替代|Firefox仍是市面上替代Chromium浏览器的唯一先进选择
- 深陷|信贷产品当道,年轻人深陷其中,“花呗们”该不该背锅?
- 黑科技|又一产品被央视曝光,披着“黑科技”外衣,其实在收割智商税
