当前位置: 首页 > 知识库问答 >
问题:

react.js - 为什么React中input设定了value(不设置onChange)后 就无法不能被修改了?

诸葛卜霸
2024-08-26

demo

这个Demo中有两个 input,一个是 React组件中的input 一个是 通过document.createElement创建的input.
这两个input都设置了name和value. 他们之间的区别是:
第一个input无法输入,第二个input可以正常输入.

问题: 为什么会有这样的区别?

image.png
上面这段文字好像只在react中生效. 传统domAPI创建的input并没有这样的限制.

共有2个答案

小牛23164
2024-08-26

React中受控组件的概念。会有一个自动处理,在每次输入后将输入框恢复到指定的 value
�� <input> – React 中文文档

陷阱

如果传递了 value 但没有传递 onChange,那么将无法输入内容。当你通过传递 value 来控制输入框时,你需要保证输入框始终具有你传递的值。因此,如果你将一个 state 作为 value 传递,但在 onChange 事件处理程序中忘记同步更新该状态变量,React 将在每次输入后将输入框恢复到指定的 value


DOM元素会有一个内置的 value 属性,也就是我们经常会遇到的 event.target.value。和我们在React/Vue 中绑定的 State 并不是同步的。
一般都是需要我们去手动监听 input/change 事件来收集DOM元素的 target.value,然后赋值给绑定的 state。同理 state 变更之后也需要去设置DOM元素的 target.value(只不过这一侧的修改多数都是由框架帮助实现了,Vue 是双向都自动处理了)。

之前在 Vue 的社区中遇到一个类似的问题 �� vue3中input的value和绑定的ref存在不同的问题 · vuejs/core · Discussion #7793 希望对你有帮助。

当时我还写的一篇相关的笔记 �� 绑定的 value 值和元素的 value 值

周祺
2024-08-26

在React中,当你为<input>元素设置了value属性而没有同时设置onChange事件处理器时,你会遇到输入字段无法被用户修改的情况。这是因为React的受控组件(controlled components)机制。

解释

在React中,<input>, <textarea>, 和 <select> 元素等表单元素通常被称为“受控组件”,因为React通过其状态(state)来控制这些元素的值。当你为这些元素设置value属性时,React会期望你通过某种方式(通常是onChange事件)来更新这个值。

  • 受控组件:在React中,表单数据(如用户输入)由React组件的状态管理。这意味着每当表单字段的值发生变化时,你应该更新组件的状态,从而触发组件的重新渲染,并显示新的值。这通常是通过在<input>元素上设置value属性并将其链接到组件的状态,并在onChange事件处理器中更新这个状态来实现的。
  • 非受控组件:另一方面,非受控组件允许表单数据由DOM本身处理,而React组件不直接跟踪其值。这通常通过不设置value属性(或将其设置为undefined),并允许浏览器处理输入来实现。然而,在React中,通常推荐使用受控组件,因为它们提供了更一致和可预测的行为。

为什么React中的input无法被修改?

在你的例子中,React组件中的<input>元素被赋予了value属性,但没有提供onChange事件处理器来更新这个值。因此,React会保持这个value属性的值不变,即使DOM尝试更新它(例如,用户尝试输入文本)。这导致了一个看似“无法修改”的输入字段。

解决方案

要使React中的<input>元素可编辑,你需要添加一个onChange事件处理器,该处理器会更新组件的状态,从而允许React知道何时应该更新DOM中的值。例如:

class MyComponent extends React.Component {
  constructor(props) {
    super(props);
    this.state = { value: '' };

    this.handleChange = this.handleChange.bind(this);
  }

  handleChange(event) {
    this.setState({ value: event.target.value });
  }

  render() {
    return <input type="text" value={this.state.value} onChange={this.handleChange} />;
  }
}

在这个例子中,每当用户输入文本时,onChange事件会被触发,handleChange方法会被调用,该方法会更新组件的状态,从而允许<input>元素显示新的值。

 类似资料:
  • 我正在尝试设置React组件中的状态,以便它在子组件的输入值发生变化时进行更改。我可以console.log和并获得预期的字符串,但是我不能编译这个函数: 我很困惑,因为我在我的。 我的getInitialState是:

  • 我没有在我的中设置,但是我可以使用和! 我的如下所示: 如果我想安装其他版本的JDK,比如11、14、15.…,我该如何使用它呢?我需要设置吗?

  • 问题内容: 我正在尝试使用GoLang,接口和结构继承。 我创建了一组结构,其想法是可以将常见方法和值保留在核心结构中,然后仅继承此结构并适当添加其他值: 您还可以在下面的游乐场中找到: https://play.golang.org/p/OxzuaQkafj 但是,当我运行main方法时,年龄保持为“ 21”,并且不会被SetAge()方法更新。 我试图了解为什么会这样,以及我需要做些什么才能使

  • 本文向大家介绍为什么用relu就不用sigmoid了相关面试题,主要包含被问及为什么用relu就不用sigmoid了时的应答技巧和注意事项,需要的朋友参考一下 参考回答: Sigmoid的导数只有在0的附近时有比较好的激活性,在正负饱和区域的梯度都接近0,会导致梯度弥散。而relu函数在大于0的部分梯度为常数,不会产生梯度弥散现象。Relu函数在负半区导数为0,也就是说这个神经元不会经历训练,就是

  • 我在Ubuntu中安装JDK有困难,我不能让它工作。谁能让我知道我做错了什么? 1-我从Oracle的网站下载了jdk-6u35-linux-i586.bin 2-我将下载的文件移到了家里/ 3-我使用chmod+x jdk-6u35-linux-i586.bin将其转换为可执行文件 4-我使用sudo./jdk1.6.0_35执行它 5-我使用mv jdk1.6.0_35//usr/local/

  • 问题内容: 我正在使用以下代码(尝试)查询数据库: 其中clientRequest [0]来自字符串数组,服务变量是POJO中的字符串,映射到MySQL数据库中的VARCHAR(45)。 当我运行此代码时,Hibernate将执行的SQL查询显示为: 这使我相信clientRequest [0]的值未正确设置为参数。 我检查了clientRequest [0]包含一个有效的String,它确实这样

  • 问题内容: 所以我已经在Java编程学了一个学期左右的时间,而且我遇到了几次这个问题,最后才开始提出问题。 如果我做一个然后设置大小,例如。帧实际上并不长。据我所知,它实际上更长。另外,如果您将垂直尺寸设置得非常小(低于30),则框架甚至不会显示,只有操作系统顶部的窗口栏和框架才会变大,直到您将值超过30(这样看起来与)相同。为什么会这样,修复起来并不难,但是很奇怪,我很好奇为什么会这样? 如果您

  • 我使用JavaFX Scene Builder1.1创建了一个FXML文件。默认情况下创建AnchorPane。为什么我不能修改resizable属性?