我已经看到examples展示了如何在React中实现双向绑定,但是没有一个解释该功能在内部的实际功能。
在codepen example中摘自React网站,如果您注释掉第11行:
handleChange(event) {
// this.setState({value: event.target.value});
}
您将注意到即使用户直接修改输入框后,视图也不会以与数据模型不一致的方式进行更新,从而注意到React如何实施2向绑定。但是它是怎么做到的?
鉴于event.target.value
的输入方式是用户刚刚在handleChange
范围内输入的,但是在视图中仍然为空,这意味着该值有时已由React重置。另外,它不是将值简单地重置为空,而是根据最新的数据模型,可以通过对代码进行以下更改来进行测试:
constructor(props) {
super(props);
this.state = {value: ''};
this.handleChange = this.handleChange.bind(this);
this.handleSubmit = this.handleSubmit.bind(this);
this.counter = 0;
}
handleChange(event) {
if (this.counter < 3) {
this.setState({value: event.target.value});
this.counter++;
}
}
这一次,输入框会前三次更改,然后根据最后的模型状态重置。
我的猜测如下:
如果状态已更改,则缓存的Virtual-DOM表示将被“污染”,这将触发虚拟元素的重新呈现。但是,我在上面描述的其余流程中仍然适用,这意味着将不会创建新的HTML节点,而只会更新现有HTML节点的属性(假设元素类型为<input>
,没有变化)。
关于此功能的内部机制,这是我的最佳猜测。如果我错了,请告诉我,如果真的错了,那么问题的真正答案是什么。
谢谢!
答案 0 :(得分:1)
这是一个简单的问题,我会尽力而为,如果有人发现我的回答有任何错误,请指出来,我将很乐意输入更正内容!挖掘React源代码,这就是我想出的东西:
1-修改了HTML,并在DOM中调用了一个事件
2-React在EventPropoagators.js内将事件/综合事件分派排队
3-事件按顺序出队(此事件对状态没有影响)
4-在事件循环结束时,react使用restoreTarget
来还原受控组件以表示React Controlled Component.js中的状态:
用于在更改事件触发后恢复受控状态。
我们在事件循环结束时执行此转换,以便我们 总是在这里收到正确的光纤
这就是魔术发生的地方。 restoreTarget
是组件的state
,因此react此时会触发常规的render()
重绘restoreTarget
,我想这会通过标准的virtual-DOM与real- DOM协调算法。
根据您的示例,执行handleChange()
(有或无状态更改)之后,将重绘restoreTarget
并呈现一个组件,该组件准确地表示count = 3
当时的状态。
答案 1 :(得分:0)
我将通过一个示例展示React的两种绑定方式。 设置一个React应用程序
import React, { Component } from 'react';
import './App.css';
import Person from './Person/Person';
class App extends Component {
state = {
persons: [
{
name: "VK",
age: 29
},
{
name: "HK",
age: 28
}
]
}
nameChangedHandler = (event) => {
this.setState(
{
persons: [
{
name: "VK",
age: 29
},
{
name: event.target.value,
age: 28
}
],
groupName: "Vishita"
}
);
}
render() {
return (
<div className="App">
<h1>Vinit Khandelwal</h1>
<p>And here is my resume</p>
<Person
name={this.state.persons[0].name}
age={this.state.persons[0].age} />
<Person
name={this.state.persons[1].name}
age={this.state.persons[1].age}
changed={this.nameChangedHandler} >Hobby: Shopping</Person>
</div>
);
}
}
export default App;
import React from 'react';
const person = (props) => {
return (
<div>
<p>I am {props.name}. I am {props.age} years old!</p>
<p onClick={props.click}>{props.children}</p>
<input type="text" onChange={props.changed} value={props.name} />
</div>
);
}
export default person;
此示例通过定义一个函数并调用该函数,传递事件并使用事件的值来展示React中的两种方式绑定。