还是之前写过的一个组件
import React from "react"
export default class index extends React.Component{
constructor(props){
super(props);
this.state = {
name: "小猫猫"
}
}
componentDidMount = ()=>{
document.title = this.state.name;
}
componentDidUpdate() {
document.title = this.state.name;
}
render(){
return (
<div>
Hello World
<button onClick= { ()=>{ this.setState({ name: "大猫猫" }) } }>更改title</button>
</div>
)
}
}
我们通过 componentDidMount 在页面加载完毕时 将state中的name属性 写入到页面title标签中
显然运行时 已经没有问题
然后 我们通过给 更改title 这个按钮添加点击事件 然后 更改state下的name的值 因为我们直接这样改 title他是无法触发数据相应去给他改的 所以 我们要通过componentDidUpdate 生命周期去监听 如果响应式数据更改了 再将他写入title
但是 显然 这样 万一 我们改的是其他数据 那么 他依旧会执行这个 将name写入title的逻辑 非常不友好
我们可以更改组件代码如下
import React from "react"
export default class index extends React.Component{
constructor(props){
super(props);
this.state = {
name: "小猫猫",
cont: 1
}
}
componentDidMount = ()=>{
document.title = this.state.name;
}
componentDidUpdate(props,state) {
if(state.name !== this.state.name){
document.title = this.state.name;
console.log("state.name",state.name);
console.log("this.state.name",this.state.name);
console.log("触发");
}
}
render(){
return (
<div>
Hello World
<button onClick= { ()=>{ this.setState({ name: "大猫猫" }) } }>更改title</button>
<button onClick= { ()=>{ this.setState({ cont: 2 }) } }>更改cont</button>
</div>
)
}
}
简单说 我们利用了 componentDidUpdate 的参数 它可以拿到两个参数 分别是 props父组件传过来的值 还有 state组件的 state
注意 你用 this.state 拿到的是更改后的值 但 这个参数接到的 state 是本次修改前的内容
所以 只需要判断 this.state 和 函数参数的 state 中的name是不是完全一样 就能判断到 这次修改有没有改到name
为了让大家看到清楚 我特意加了个 cont
方便大家看
那么 我们运行项目 不管点击多少次 更改cont 都不胡触发到if(state.name !== this.state.name){中的逻辑
然后我们点击 更改title
第一次 逻辑就会顺利 触发 可以看到 state.name 拿到的是我们更改之前的值小猫猫 this.state.name 拿到的是我们更改之后的值 大猫猫
但是你点击过一次之后肯定是无法再触发了 因为之后他们就都等于 大猫猫了 自然是判断不到他们不同了
这是我们之前用类实现的形式
那么 后面 我们就来看看 Effect Hook 的写法
我们编写代码如下
import React,{ useState,useEffect } from "react"
const MyComponent = () => {
const [name,setName] = useState("小猫猫");
const [cont,setCont] = useState(1);
useEffect(() => {
document.title = name;
console.log("name值被更改了");
},[name])
return (
<div>
Hello World
{ cont }
<button onClick={ ()=> { setCont(cont+1)} }>更改cont</button>
<button onClick={ ()=> { setName("大猫猫")} }>更改title</button>
</div>
);
};
export default MyComponent;
大家可能看着有点懵 其实利用的就是useEffect第二个参数 是个数组 我们这里单放一个name 意思就是 useEffect 之间听name更改
当然 我们之前说过 useEffect 也带有 componentDidMount 的特性 所以 一进来会先触发一次 然后 name第一次改变 所以 一进来 它一共改变了两次
然后 我们点击更改cont
可以看到 不管怎么点 都不会触发了
然后我们点击更改title
可以看到 这样就触发了
当然 useEffect 可以写多个
也可以拿来当监听器用 这个其实还是非常好用的
如下图 两个都是可以起到自己的作用的