文章详情

短信预约-IT技能 免费直播动态提醒

请输入下面的图形验证码

提交验证

短信预约提醒成功

React源码中怎么实现受控组件

2024-04-02 19:55

关注

本篇内容主要讲解“React源码中怎么实现受控组件”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“React源码中怎么实现受控组件”吧!

在React中一个简单的受控组件如下:

function App() {   const [num, updateNum] = React.useState(0);      const onChange = ({target: {value}}) => {     updateNum(value);   }    return (     <input value={num} onChange={onChange}/>   ) }

在onChange中会更新num,num作为value prop传递给<input/>,达到value受控的目的。

如果让你来设计,你会怎么做?

我相信大部分同学第一个想法是:将value prop与其他attribute prop一样处理就行。

我们知道React内部运行有3个阶段:

假设我们要在onChange中触发更新改变className,只需要在render阶段记录要改变的className,在commit阶段执行对应的addClass DOM操作。

同样的,如果我们要在onChange中触发更新改变value,只需要在render阶段记录要改变的value,在commit阶段执行对应的inputDOM.setAttribute('value', value)操作。

这样逻辑非常通顺。那么事实上呢?

直接改变value的问题
className只是inputDOM上的一个普通属性。而value则涉及到输入框光标的位置。

如果我们直接修改value,那么属性改变后input的光标输入位置也会丢失,光标会跳到输入框的最后。

想想我们将1234修改为12534。

1234 --> 12534

需要先将光标位置移动到2之后,再输入5。

如果setAttribute('value', '12534'),那么光标不会保持在5后面而是跳到4后面。

那么React如何解决这个问题呢?

用非受控的形式实现受控组件

你没有看错,React用非受控形式实现了受控组件的逻辑。

简单的说,不同于className在commit阶段受控更新,value则完全是非受控的形式,只在必要的时候受控更新。

因为一旦更新value,那么光标位置就会丢失。

我们稍微修改下Demo,input为受控组件,value始终为1:

function App() {   const num = 1;    return (     <input value={num}/>   ) }

当我们在源码中打上断点,输入2后,实际上会先显示12,再删掉2。

只不过这个删除的过程是同步的所以看起来输入框内始终只有1。

React源码中怎么实现受控组件

所以,不同于React其他组件props的更新会经历schedule - render - commit流程。

对于input、textarea、select,React有一条单独的更新路径,这条路径触发的更新被称为discreteUpdate。

这条路径的工作流程如下:

  1. 鸿蒙官方战略合作共建——HarmonyOS技术社区

  2. 先以非受控的形式更新表单DOM

  3. 以同步的优先级开启一次更新

  4. 更新后的value在commit阶段并不会像其他props一样作用于DOM

  5. 调用restoreStateOfTarget方法,比较DOM的实际value(即步骤1中的非受控value)与步骤3中更新的value,如果相同则退出,如果不同则用步骤3的value更新DOM

什么情况下这2个value会相同呢?

我们正常的受控组件就是相同的情况:

function App() {   const [num, updateNum] = React.useState(0);      const onChange = ({target: {value}}) => {     updateNum(value);   }    return (     <input value={num} onChange={onChange}/>   ) }

什么情况下这2个value会不同呢?

上面的Demo中,虽然受控,但是没有调用updateNum更新value的情况:

function App() {   const num = 1;    return (     <input value={num}/>   ) }

在这种情况下,步骤1的非受控value变为了12,步骤3的受控value还是1,所以最终会用1再更新下DOM的value。

到此,相信大家对“React源码中怎么实现受控组件”有了更深的了解,不妨来实际操作一番吧!这里是编程网网站,更多相关内容可以进入相关频道进行查询,关注我们,继续学习!

阅读原文内容投诉

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

软考中级精品资料免费领

  • 历年真题答案解析
  • 备考技巧名师总结
  • 高频考点精准押题
  • 2024年上半年信息系统项目管理师第二批次真题及答案解析(完整版)

    难度     813人已做
    查看
  • 【考后总结】2024年5月26日信息系统项目管理师第2批次考情分析

    难度     354人已做
    查看
  • 【考后总结】2024年5月25日信息系统项目管理师第1批次考情分析

    难度     318人已做
    查看
  • 2024年上半年软考高项第一、二批次真题考点汇总(完整版)

    难度     435人已做
    查看
  • 2024年上半年系统架构设计师考试综合知识真题

    难度     224人已做
    查看

相关文章

发现更多好内容

猜你喜欢

AI推送时光机
位置:首页-资讯-后端开发
咦!没有更多了?去看看其它编程学习网 内容吧
首页课程
资料下载
问答资讯