React学习之diff算法
1. 前言
2. 验证diff
<!DOCTYPE html>
<html lang="en">
<head>
<style>
.box {
width: 300px;
height: 150px;
overflow: auto;
background-color: skyblue;
}
.news {
height: 30px;
}
</style>
</head>
<body>
<div id="test1"></div>
<!-- render 函数的执行结果就是 vdom,也就是 React Element 的实例 -->
<!-- 页面状态有更新时,根据 key 对比同层级虚拟 dom,如果发生变化则增删改真实 dom -->
<!-- 同层级:span 内的 input 输入内容也不会重新生成真实 dom -->
<script type="text/babel">
class Time extends React.Component {
state = {
date: new Date(),
};
render() {
return (
<div>
<h1>hello</h1>
<input type="text" name="" id="" />
<br />
<br />
<span>
现在是:{this.state.date.toTimeString()}
<input type="text" name="" id="" />
</span>
</div>
);
}
// componentDidMount ==> diffing ==> render
componentDidMount() {
setInterval(() => {
this.setState({ date: new Date() });
}, 1000);
}
}
ReactDOM.render(<Time />, document.getElementById('test1'));
</script>
</body>
</html>
3. key的作用
<!DOCTYPE html>
<html lang="en">
<body>
<div id="test1"></div>
<script type="text/babel">
class Time extends React.Component {
state = {
per: [
{ name: '小野', age: 18, id: 1 },
{ name: '友树', age: 19, id: 2 },
],
};
render() {
return (
<div>
<h1>おはようございます</h1>
<button onClick={this.add}>添加砂糖</button>
<div
ref={(c) => {
this.box = c;
}}
>
{this.state.per.map((p, index) => {
return (
<p key={index}>
{p.name}
{p.age}
</p>
);
})}
</div>
</div>
);
}
componentDidMount() {
setInterval(() => {}, 1000);
}
add = () => {
const { per } = this.state;
const newPer = { name: '砂糖', age: 20, id: per.length + 1 };
this.setState({ per: [newPer, ...per] });
};
}
ReactDOM.render(<Time />, document.getElementById('test1'));
</script>
</body>
</html>
3.1 key是index
初始数据:
{ name: '小野', age: 18, id: 1 },
{ name: '友树', age: 19, id: 2 },
初始虚拟dom:
<p key={1}>
小野18
</p>
<p key={2}>
友树19
</p>
更新数据:
{ name: '砂糖', age: 20, id:3 },
{ name: '小野', age: 18, id: 1 },
{ name: '友树', age: 19, id: 2 },
更新虚拟dom:
<p key={1}>
砂糖20
</p>
<p key={2}>
小野18
</p>
<p key={3}>
友树19
</p>
新旧虚拟dom对比,三个节点全都需要生成 true dom
3.2 key是id
初始数据:
{ name: '小野', age: 18, id: 1 },
{ name: '友树', age: 19, id: 2 },
初始虚拟dom:
<p key={1}>
小野18
</p>
<p key={2}>
友树19
</p>
更新数据:
{ name: '砂糖', age: 20, id:3 },
{ name: '小野', age: 18, id: 1 },
{ name: '友树', age: 19, id: 2 },
更新虚拟dom:
<p key={3}>
砂糖20
</p>
<p key={1}>
小野18
</p>
<p key={2}>
友树19
</p>
新旧虚拟dom对比,1、2不变;仅3不存在,生成 true dom