想象一下,我们有一个带有复选框的基于功能的简单组件。
我很好奇为什么随后添加和删除事件侦听器成功的原因:
function Component() {
const handler = () => 123
useEffect(() => {
window.addEventListener("beforeunload", handler)
window.removeEventListener("beforeunload", handler)
}, [isChecked])
}
但是,当引入条件时,例如:
function Component() {
const handler = () => 123
useEffect(() => {
isChecked
? window.addEventListener("beforeunload", handler)
: window.removeEventListener("beforeunload", handler)
}, [isChecked])
}
已添加侦听器,但不再删除。
那是为什么?是因为我们的处理程序是在重新渲染时重新创建的吗?当处理程序移到组件外部时,一切都按顺序进行。
这是一个想要测试它的演示:
https://codesandbox.io/s/y8jono6yx?module=%2Fsrc%2FCheckbox.jsx
说明:
npm i
npm start
来启动开发服务器至少在Chrome中,可以通过调用getEventListeners(window)
来检索事件侦听器列表。
答案 0 :(得分:2)
问题在于apiVersion: extensions/v1beta1
kind: Deployment
metadata:
name: myDeploymentName
labels:
app: SomeLabel1
label2: SomeLabel2
spec:
replicas: 100
strategy:
type: RollingUpdate
template:
metadata:
labels:
app: SomeLabel1
label2: SomeLabel2
spec:
containers:
- name: myPodName
image: myPod:latest
imagePullPolicy: Always
ports:
- name: myPodPort
containerPort: 8080
是每个组件渲染上的新功能。 handler
是空操作,因为此window.removeEventListener("beforeunload", handler)
函数从未被注册为handler
侦听器。
beforeunload
应该移出组件函数的范围:
handler
由于const handler = () => 123;
export default function Checkbox() {
const [isChecked, setIsChecked] = useState(false);
useEffect(
() => {
isChecked
? window.addEventListener("beforeunload", handler)
: window.removeEventListener("beforeunload", handler);
},
[isChecked]
);
...
};
不能以这种方式访问组件功能范围,因此可以在那里做的事情非常有限。一种更传统的方法是使handler
回调仅执行一次(与useEffect
对应)并从componentDidMount
返回一个函数(与useEffect
对应)。由于在componentWillUnmount
函数范围内使用了相同的handler
,因此问题消失了,但是另一个问题是useEffect
不能与handler
一起使用,因为useState
handler
中使用的“函数”是在初始渲染期间定义的函数,useEffect
在其范围内将始终为isChecked
。 false
可以用于此目的(demo):
useRef