bam*_*ami 3 reactjs react-hooks react-lifecycle-hooks
我真的很想了解 React 功能组件的生命周期。在许多网站中,您会看到这三个步骤:
1-安装2-渲染3-卸载。
但是,在 useeffect() 函数之前编写的其他代码又如何呢,例如假设:
const Countdown = () => {
let x = 0;
const [countDown, setCountDown] = useState(10)
x = x + 1
if(x > 100) {
x = 0
}
useEffect(() => {
const interval = setInterval(() => {
setCountDown(countDown - 1);
console.log(x)
}, 1000);
}, [countDown]);
};
Run Code Online (Sandbox Code Playgroud)
我想知道 :
当 countDown 状态和 x 变量在 useEffect 之前或之后(或内部)声明时?
当if或for 短语被声明时(在此示例if短语中),它们确实在 useEffect 内吗?
什么是加载页面顺序?执行的起点是什么?
\n\n1-安装 2-渲染 4-卸载。
\n
它更像是(文档):
\nuseLayoutEffect)useEffect))useLayoutEffect)useEffect))\n\n当 countDown 状态和 x 变量在 useEffect 之前或之后(或内部)声明时?
\n
前。React 库无法更改 JavaScript 代码执行的方式。调用useState和关联的声明位于useEffect调用之前,因此它们发生在调用之前。
\n\n当声明 if 或 for 短语时(在本例中为 if 短语),它们确实在 useEffect 内吗?
\n
不,只有回调中的代码useEffect才会被调用作为效果。
这里的循环是:
\nx变量并将其设置为0.countDownandsetCountDown并调用useState,它在实例存储中分配一个状态槽;你的代码存储了什么useState返回的内容(初始状态值和设置器)存储在这些常量中。x = x + 1语句运行,更新x为1.if语句运行,但条件永远不会为真\xc2\xa0\xe2\x80\x94x是一个局部变量,而不是一个状态成员,所以它的值永远是1这一点上。useEffect安排了效果回调countDown。Countdown。Countdown并提交到 DOM(使 DOM 显示它们所描述的内容)。useEffect回调(useEffect回调始终在挂载后立即调用)\nsetCountDown.x,这将是1.setCountDown,改变值。x变量并将其设置为0.countDownandsetCountDown并调用useState,它从实例存储中检索更新的状态;你的代码存储了什么useState返回的内容(当前状态值和设置器)存储在这些常量中。x = x + 1语句运行,更新x为1.if语句可以运行,但条件永远不会为真。useEffect在更改时安排效果回调countDown。Countdown。countDown发生了变化,React 会调用您的useEffect回调\nsetCountDown.x将是1.您显示的代码中有几个错误
\ncountDown。这将很快导致数百甚至数千个计时器全部触发更新调用。您应该:\ncountDown依赖项,因此效果仅在安装时运行。然后使用 的回调形式setCountDown。x,但它是局部变量,因此每次都会重新创建。countDown当到达 时,没有什么特别的事情发生0,所以它会继续前进-1,-2等等。这是带有一些注释的更新版本。我本来打算删除它,x因为它并没有真正用于任何用途,但后来认为最好留下评论。我没有对上面的#4 做任何事情,因为我不确定你想做什么。
const Countdown = () => {\n let x = 0;\n const [countDown, setCountDown] = useState(10);\n\n x = x + 1;\n if (x > 100) { // `x` will always be `1` here, remember that\n x = 0; // `x` is a *local variable*\n }\n\n useEffect(() => {\n const interval = setInterval(() => {\n // Use the callback form of the setter so you can update the\n // up-to-date value\n setCountDown((c) => c - 1);\n // Will always show 1\n console.log(x);\n }, 1000);\n // Return a cleanup callback that removes the interval timer\n return () => {\n clearInterval(interval);\n };\n }, []);\n // ^^ don\'t use `countDown` as a dependency (in this particular case),\n // since we don\'t use it (anymore, now we use the callback setter)\n\n // Return some elements\n return <div>{countDown}</div>;\n};\nRun Code Online (Sandbox Code Playgroud)\nconst Countdown = () => {\n let x = 0;\n const [countDown, setCountDown] = useState(10);\n\n x = x + 1;\n if (x > 100) { // `x` will always be `1` here, remember that\n x = 0; // `x` is a *local variable*\n }\n\n useEffect(() => {\n const interval = setInterval(() => {\n // Use the callback form of the setter so you can update the\n // up-to-date value\n setCountDown((c) => c - 1);\n // Will always show 1\n console.log(x);\n }, 1000);\n // Return a cleanup callback that removes the interval timer\n return () => {\n clearInterval(interval);\n };\n }, []);\n // ^^ don\'t use `countDown` as a dependency (in this particular case),\n // since we don\'t use it (anymore, now we use the callback setter)\n\n // Return some elements\n return <div>{countDown}</div>;\n};\nRun Code Online (Sandbox Code Playgroud)\r\nconst { useState, useEffect } = React;\n\nconst Countdown = () => {\n let x = 0;\n const [countDown, setCountDown] = useState(10);\n\n x = x + 1;\n if (x > 100) { // `x` will always be `1` here, remember that\n x = 0; // `x` is a *local variable*\n }\n\n useEffect(() => {\n const interval = setInterval(() => {\n // Use the callback form of the setter so you can update the\n // up-to-date value\n setCountDown((c) => c - 1);\n // Will always show 1\n console.log(x);\n }, 1000);\n // Return a cleanup callback that removes the interval timer\n return () => {\n clearInterval(interval);\n };\n }, []);\n // ^^ don\'t use `countDown` as a dependency (in this particular case),\n // since we don\'t use it (anymore, now we use the callback setter)\n\n // Return some elements\n return <div>{countDown}</div>;\n};\n\nconst Example = () => {\n return <Countdown />;\n};\n\nconst root = ReactDOM.createRoot(document.getElementById("root"));\nroot.render(<Example />);Run Code Online (Sandbox Code Playgroud)\r\n如果我们希望倒计时在到达时停止0并关闭计时器,我们可以通过几种方法来做到这一点,请参阅两个实时示例中显示不同方法的注释:
<div id="root"></div>\n\n<script src="https://cdnjs.cloudflare.com/ajax/libs/react/18.1.0/umd/react.development.js"></script>\n<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/18.1.0/umd/react-dom.development.js"></script>Run Code Online (Sandbox Code Playgroud)\r\nconst { useState, useEffect } = React;\n\nconst Countdown = () => {\n const [countDown, setCountDown] = useState(10);\n\n useEffect(() => {\n const interval = setInterval(() => {\n // We could cancel the interval from within the setter\n // callback. It\'s a bit dodgy, though, to have side-\n // effects in setter callbacks.\n setCountDown((c) => {\n const updated = c - 1;\n if (updated === 0) {\n clearInterval(interval);\n }\n return updated;\n });\n }, 1000);\n return () => {\n clearInterval(interval);\n };\n }, []);\n\n return <div>{countDown === 0 ? "Done" : countDown}</div>;\n};\n\nconst Example = () => {\n return <Countdown />;\n};\n\nconst root = ReactDOM.createRoot(document.getElementById("root"));\nroot.render(<Example />);Run Code Online (Sandbox Code Playgroud)\r\n<div id="root"></div>\n\n<script src="https://cdnjs.cloudflare.com/ajax/libs/react/18.1.0/umd/react.development.js"></script>\n<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/18.1.0/umd/react-dom.development.js"></script>Run Code Online (Sandbox Code Playgroud)\r\nconst { useState, useEffect, useRef } = React;\n\nconst Countdown = () => {\n // We could store the timer handle in a ref (which is maintained\n // across renders) and use a second `useEffect` to cancel it when\n // `countDown` reaches zero.\n const intervalRef = useRef(0);\n const [countDown, setCountDown] = useState(10);\n\n useEffect(() => {\n intervalRef.current = setInterval(() => {\n setCountDown((c) => c - 1);\n }, 1000);\n return () => {\n // (It\'s okay if this tries to clear an interval that\n // isn\'t running anymore.)\n clearInterval(intervalRef.current);\n };\n }, []);\n\n useEffect(() => {\n if (countDown === 0) {\n clearInterval(intervalRef.current);\n }\n }, [countDown]);\n\n return <div>{countDown === 0 ? "Done" : countDown}</div>;\n};\n\nconst Example = () => {\n return <Countdown />;\n};\n\nconst root = ReactDOM.createRoot(document.getElementById("root"));\nroot.render(<Example />);Run Code Online (Sandbox Code Playgroud)\r\n| 归档时间: |
|
| 查看次数: |
310 次 |
| 最近记录: |