旧版生命周期
<script type="text/babel">
/*
1.初始化阶段:render() 触发初次渲染
a.constructor()
b.componentWillMount()
c.render()
d.componentDidMount()
2.更新阶段:由组件内部this.setState()或父组件重新render触发
a.shoudComponentUpdate()
b.componentWillUpdate()
c.render()
d.componentDidUpdate()
3.卸载组件:由ReactDOM.unmountComponentAtNode()触发
a.componentWillUnmount()
*/
class Life extends React.Component {
//
constructor(props) {
console.log("constructor");
super(props);
// 初始化状态
this.state = {
count: 0,
};
}
//组件将要挂载的钩子函数
componentWillMount() {
console.log("componentWillMount");
}
//组件挂载完成的钩子函数
componentDidMount() {
console.log("componentDidMount");
}
//组件state更新的钩子函数
shouldComponentUpdate(){
console.log('shouldComponentUpdate');
// 控制组件更新的阀门,只能是布尔值
return true
}
//组件将要更新的钩子函数
componentWillUpdate() {
console.log("componentWillUpdate");
}
//组件更新的钩子函数
componentDidUpdate() {
console.log("componentDidUpdate");
}
//组件将要卸载的钩子函数
componentWillUnmount() {
console.log("componentWillUnmount");
}
// 点击+1
add = () => {
let { count } = this.state;
this.setState({
count: count + 1,
});
};
// 卸载组件
death = () => {
ReactDOM.unmountComponentAtNode(document.getElementById("app"));
};
force = () => {
// 强制更新
this.forceUpdate()
};
render() {
const { count } = this.state;
console.log("render");
return (
<div>
<h3>当前求和为{count}</h3>
<button onClick={this.add}>点我+1</button>
<button onClick={this.death}>卸载组件</button>
<button onClick={this.force}>不改变数据,强制更新页面</button>
</div>
);
}
}
// 渲染组件
ReactDOM.render(<Life />, document.getElementById("app"));
</script>
新版生命周期
<script type="text/babel">
/*
1.初始化阶段:render() 触发初次渲染
a.constructor()
b.componentWillMount() 新版本中移除,实在想用需要加 UNSAFE_
c.render()
d.componentDidMount()
2.更新阶段:由组件内部this.setState()或父组件重新render触发
a.shoudComponentUpdate()
b.componentWillUpdate() 新版本中移除,实在想用需要加 UNSAFE_
c.render()
d.componentDidUpdate()
3.卸载组件:由ReactDOM.unmountComponentAtNode()触发
a.componentWillUnmount()
*/
class Life extends React.Component {
//
constructor(props) {
console.log("constructor");
super(props);
// 初始化状态
this.state = {
count: 0,
};
}
//组件挂载完成的钩子函数
componentDidMount() {
console.log("componentDidMount");
}
//组件state更新的钩子函数
shouldComponentUpdate() {
console.log("shouldComponentUpdate");
// 控制组件更新的阀门,只能是布尔值
return true;
}
//组件更新的钩子函数
getSnapshotBeforeUpdate() {
console.log("getSnapshotBeforeUpdate");
return `hello world`;
}
//组件更新的钩子函数
componentDidUpdate(preProps,preState,snapshot) {
console.log("componentDidUpdate",snapshot);
}
//组件将要卸载的钩子函数
componentWillUnmount() {
console.log("componentWillUnmount");
}
// 点击+1
add = () => {
let { count } = this.state;
this.setState({
count: count + 1,
});
};
// 卸载组件
death = () => {
ReactDOM.unmountComponentAtNode(document.getElementById("app"));
};
force = () => {
// 强制更新
this.forceUpdate();
};
render() {
const { count } = this.state;
console.log("render");
return (
<div>
<h3>当前求和为{count}</h3>
<button onClick={this.add}>点我+1</button>
<button onClick={this.death}>卸载组件</button>
<button onClick={this.force}>不改变数据,强制更新页面</button>
</div>
);
}
}
// 渲染组件
ReactDOM.render(<Life />, document.getElementById("app"));
</script>
diff算法中key的作用
<script type="text/babel">
/*
diff算法:
1.key的原理
key是虚拟DOM的标识,在数据更新的时候有很大的作用
当状态中的数据发生变化的时候,react会根据新数据生成新的虚拟DOM,
然后根据新、旧虚拟DOM进行diff比较,规则如下:
a.key值未找到
创建新的DOM节点,渲染到页面上
b.key值相同
如果虚拟DOM中的内容没变,复用节点
如果内容改变,生成新的DOM。随后替换之前的节点
2.为什么不建议使用索引作key
a.对数据进行:逆序添加、逆序删除等破坏顺序的操作
b.如果页面结构中包含输入类标签
*/
// 精简代码
class Person extends React.Component {
state = {
persons: [
{
id: 1,
name: "徐晓红",
age: 12,
},
{
id: 2,
name: "徐晓蓝",
age: 15,
},
],
};
render() {
let { name, age, sex } = this.props;
return (
<div>
<ul>
{this.state.persons.map((item, index) => {
return (
<li key={index}>
{item.name}---{item.age}
</li>
);
})}
</ul>
</div>
);
}
}
ReactDOM.render(<Person />, document.getElementById("app"));
</script>