function Counter() { const [count, setCount] = useState(0); useEffect(() => { setTimeout(() => { console.log(count) }, 3000) }) // 在3秒内快速点击5次按钮,控制台打出的结果是什么样的? // 0 1 2 3 4 5 return ( <div> <p>You clicked {count} times</p> <button onClick={() => setCount(count + 1)}> Click me </button> </div> ); }
把上述代码改成class component的形式:
class Example extends React.Component{
constructor(props) {
super(props);
this.state = {
count: 0,
}
}
componentDidUpdate() {
setTimeout(() => {
console.log(this.state.count)
}, 3000)
}
add = () => {
const {count} = this.state;
this.setState({count: count + 1})
}
// 同样的操作,打印出的结果是 5 5 5 5 5
render() {
return (
<div>
<button onClick={this.add}>click me</button>
</div>
)
}
}
因为useEffect里面的所有东西都是每次render独立的,
尽管useEffect里面的函数延迟执行了,但是打出的count依然是当时render里面的count,这也说明了其实每次render都是独立的,里面有独立的state、effects、function
为什么在组件内部调用
useEffect
? 将 useEffect
放在组件内部让我们可以在 effect 中直接访问 count
state 变量(或其他 props)。我们不需要特殊的 API 来读取它 —— 它已经保存在函数作用域中。Hook 使用了 JavaScript 的闭包机制,而不用在 JavaScript 已经提供了解决方案的情况下,还引入特定的 React API。它在第一次渲染之后和每次更新之后都会执行。
React 保证了每次运行 effect 的同时,DOM 都已经更新完毕。
https://www.jianshu.com/p/fd17ce2d7e46