https://overreacted.io/zh-hans/how-are-function-components-different-from-classes/
01: 函数式组件,交互时所运用的数据,为当时上下文环境中的数据
let i = 0;
class App extends React.Component {
constructor() {
super();
this.state = {
name: '哈哈'
}
}
changData() {
this.setState({ name: '嘻嘻' })
}
add(){
console.log(i++)
}
render() {
return (
<div className="App">
<h4>{this.state.name}</h4>
<button onClick={() => { this.changData() }}>父组件 {this.add()} </button>
<div className='list'>
<Child tit={this.state.name}></Child>
</div>
</div>
);
}
}
02:当点击 [ 弹出 ] 按钮时,这时触发父组件onclick方法修改name值,发现弹出来的数据,并不是修改后的数据
03:当点击 [ 弹出 ] 按钮时,或者修改setCount数据,你也会发现弹出来的数据,并不是修改后的数据
function Child({ tit }) {
const [count, setCount] = React.useState(0);
function handleAlertClick() {
setTimeout(() => {
alert(tit)
alert('You clicked on: ' + count);
}, 3000);
}
return (
<div>
<h3>函数组件:</h3>
<p>点击 {count} 次数</p>
<button onClick={() => setCount(count + 1)}>点击</button>
<button onClick={handleAlertClick}> 弹出 </button>
</div>
);
}
产生这种问题的原因,因为当你触发事件时,子组件依赖的父数据或者自身的数据变化时候,组件会重新渲染执行,但是在内存队列中执行的方法中的数据为当时执行环境中的数据,并不会像class组件重新渲染后this指向是最新的对象
05:修改为及时响应,组件自身内部数据方法(useRef: 函数重新渲染,保持最新值,不会被再次初始化)
const newTit = React.useRef();
const latestMessage = useRef('');
React.useEffect(() => {
console.log('渲染');
newTit.current = tit;
latestMessage.current = count;
}, [tit, count])
function handleAlertClick() {
setTimeout(() => {
alert(newTit.current)
alert('You clicked on: ' + latestMessage.current);
}, 3000);
}