• React 踩坑--input中的value与defaultValue


    这两个月实习期时间踩了不少坑,先来谈谈有代表性的一个。

    我们知道表单是前端里很常见的一个东西,往往包含了很多数据校验逻辑。 

    React、antd 对表单元素专门做了优化处理,有了一些抽象的东西,使得他们的使用方式更统一更规范。。

    在一次需求开发中,有一块是这样的:首先渲染一个Table,里面每一项都有个“编辑”操作,点击弹出Modal框 

    如图所示:

    这个Modal框是一个表单,里面的文本框 下拉框等 都带有从Table里对应的那一项传来的默认值

    于是我习惯性地想到了设置 “defaultValue”,如下图。。

    但跑起来后发现这样一个问题:

    第一次点开弹出框,他带的默认值是正确的:

    但当我在Table里改变了此项数据再次点开,它并没有按照设想的显示改变后的选项,而是一直固定在“是”。

    解决这个问题前,先来回顾一下React的 受控和非受控组件

    “在 HTML 中,表单元素(如<input>、 <textarea> 和 <select>)之类的表单元素通常自己维护 state,并根据用户输入进行更新。而在 React 中,可变状态(mutable state)通常保存在组件的 state 属性中,并且只能通过使用 setState()来更新。我们可以把两者结合起来,使 React 的 state 成为“唯一数据源”。渲染表单的 React 组件还控制着用户输入过程中表单发生的操作。被 React 以这种方式控制取值的表单输入元素就叫做“受控组件”。” ——React docs

     

    这里有一个新的概念叫“受控组件”。那么如何理解受控组件和非受控组件呢。

    受控组件,简单的说,就是由React管理了它的value,而非受控组件的value就是原生的DOM管理的。 

    他们的写法上也有很大区别。

    例如,非受控组件这么写:

    <input type="text" defaultValue="a" />

    这个 defaultValue 其实就是原生DOM中的 value 属性。

    这样写出的来的组件,其value值就是用户输入的内容,React完全不管、也管不到输入的过程。

    而受控组件是这么写的:

    <input type="text" value={this.state.name} onChange={this.handleChange} />
    handleChange: function(e) {
      this.setState({name: e.target.value});
    }

    这里,value属性不再是一个写死的值,他是 this.state.name,而 this.state.name 是由 this.handleChange 负责管理的。 

    这个时候实际上 input 的 value 根本不是用户输入的内容。而是onChange 事件触发之后,由于 this.setState 导致了一次重新渲染。

    同时,React会优化这个渲染过程,实际上它仍然是通过设置input的value来实现的。

    但一定要注意,受控组件显示的值和用户输入的值虽然很多时候是相同的,但他们根本是两码事。

    受控组件显示的是 this.state.name 的值。你可以在handleChange中对用户输入的值做任意的处理,比如数据校验。

    对比受控组件和非受控组件的输入流程:

    • 非受控组件: 用户输入A => input 中显示A
    • 受控组件: 用户输入A => 触发onChange事件 => handleChange 中设置 state.name = “A” => 渲染input使他的value变成A

    正式因为这样,使得 React 的 state 成为唯一数据源。对于受控组件来说,输入的值始终由 React 的 state 驱动。

    所以官方强烈推荐使用受控组件,因为它能更好的控制组件的生命流程。

    所以回到我代码中的问题,解决办法就是:

    defaultValue 改成 value={this.state.XXX},然后在外边写一个 handleXXX 函数,通过 setState 来控制value的值。

    使之成为一个受控组件,这样就没问题了

  • 相关阅读:
    项目总结1--技术
    基于MFC的Opengl实现动画
    vs2010 MFC Opengl实现
    设计模式-状态模式
    设计模式-访问者模式
    设计模式-责任链模式
    设计模式-中介者模式
    设计模式-命令模式
    设计模式-备忘录模式
    设计模式-观察者模式
  • 原文地址:https://www.cnblogs.com/abcdecsf/p/13624541.html
Copyright © 2020-2023  润新知