ton*_*120 5 javascript reactjs react-hooks
我想澄清我对这里发生的事情的理解。任何改善我目前理解的细节将不胜感激。
function Timer() {
let [time, setTime] = useState(5);
useEffect(() => {
let timer = setInterval(() => {
setTime(time - 1);
}, 1000)
return () => clearInterval(timer);
}, );
return <div>{time}</div>
}
export default Timer
Run Code Online (Sandbox Code Playgroud)
https://codesandbox.io/s/cranky-chaplygin-g1r0p
time正在初始化为5.useEffect已读。它的回调必须准备好稍后触发。div呈现。useEffect的回调被执行。setInterval的回调准备好触发。当然useEffect'sreturn语句不会在这里触发,因为如果它触发它会取消计时器(并且计时器确实有效)。setInterval的回调触发将time( 到 4)的状态更改。time,一个新变量,被初始化为新的时间状态。useEffect读取一个新的,它的回调准备稍后触发。(发生这种情况是因为没有 的第二个参数useEffect())。return语句。这有效地重新渲染了div.useEffect的return语句会执行(这会禁用timer前一个中的useEffect)。我不确定什么时候会发生这种情况。useEffect的回调被执行。Cer*_*nce 28
您对事件顺序的理解是正确的。唯一缺少的是效果回调和清理的精确时间。
当组件重新渲染时,任何useEffects 都将分析其依赖项数组的变化。如果发生了变化,那么效果回调将会运行。这些回调保证按照它们在组件中声明的顺序运行。例如,下面的a始终会在 之前记录b。
const App = () => {
const [num, setNum] = React.useState(0);
React.useEffect(() => {
setInterval(() => {
setNum(num => num + 1);
}, 1000);
}, []);
React.useEffect(() => {
console.log('a', num);
}, [num]);
React.useEffect(() => {
console.log('b', num);
}, [num]);
return num;
}
ReactDOM.render(<App />, document.querySelector('.react'));Run Code Online (Sandbox Code Playgroud)
<script crossorigin src="https://unpkg.com/react@16/umd/react.development.js"></script>
<script crossorigin src="https://unpkg.com/react-dom@16/umd/react-dom.development.js"></script>
<div class='react'></div>Run Code Online (Sandbox Code Playgroud)
现在将效果清理回调添加到组合中。这些将始终在渲染运行的效果回调之前同步运行。例如,假设组件从渲染 A 开始,并且在渲染 A 中,效果挂钩返回了清理回调。然后,一些状态发生变化,并且发生到渲染 B 的转换,并且存在useEffect包含状态变化的依赖性数组。将会发生的是:
您可以在此处查看最后两个操作的源代码:
commitHookEffectListUnmount(Passive$1 | HasEffect, finishedWork);
commitHookEffectListMount(Passive$1 | HasEffect, finishedWork);
Run Code Online (Sandbox Code Playgroud)
第一个调用会调用先前渲染中的所有清理回调。第二次调用调用当前渲染的所有效果回调。当前渲染效果回调在执行之前的渲染清理回调后同步运行。
功能组件在其状态发生变化后是否“卸载”,这是否会导致之前的 useEffect 回调返回语句执行?
不,组件在其生命周期结束时仅卸载一次,React 允许useEffect通过提供一个带有return语句的空 dep 数组来执行带有钩子的回调:
useEffect(() => {
return () => {
console.log("unmounts");
};
}, []);
Run Code Online (Sandbox Code Playgroud)
组件何时卸下?
当它的父级停止渲染它时。请参阅条件渲染。
你能帮我理解,一般来说还是在我的问题中的例子中,useEffect 的 return 语句何时执行?
取决于 dep 数组:
[],则卸载。[value1,value2],则依赖项会发生变化(浅比较)。useEffect),它会在每次渲染时运行。请参阅后续问题useEffect 深入/useEffect 的使用?
| 归档时间: |
|
| 查看次数: |
2958 次 |
| 最近记录: |