dag*_*da1 29 javascript reactjs react-hooks
我有这个代码:
const App: React.FC = () => {
const [isOpen, setIsOpen] = React.useState(true);
const [maxHeight, setMaxHeight] = React.useState();
const wrapper = React.useRef<HTMLDivElement>(null);
const content = React.useRef<HTMLDivElement>(null);
const setElementMaxHeight = () => {
if (content && content.current) {
setMaxHeight(isOpen ? content.current.offsetHeight : 0);
}
};
useEffect(() => {
setElementMaxHeight();
window.addEventListener("resize", setElementMaxHeight);
return () => {
window.removeEventListener("resize", setElementMaxHeight);
};
});
const toggle = () => {
setIsOpen(!isOpen);
};
return (
<div>
<button onClick={toggle}>
<span className="nominal-result__expander fa" />
</button>
<div
className="nominal-results__list-wrapper"
ref={wrapper}
style={!!maxHeight ? { maxHeight: `${maxHeight}px` } : undefined }
>
<div className="nominal-results__list" ref={content} />
</div>
</div>
);
};
const rootElement = document.getElementById("root");
ReactDOM.render(<App />, rootElement);
Run Code Online (Sandbox Code Playgroud)
这将在每个渲染上添加和删除一个事件处理程序。
这一定是坏事吗,这真的从成为一个钩子中获得了什么吗?
这是在代码审查中提出的,我说它很糟糕,因为它在每次渲染时添加和删除了事件侦听器。
nem*_*035 21
对于这种确切的情况,您是对的,因为undefined
作为useEffect
.
这意味着useEffect
在每个渲染上运行,因此事件处理程序将不必要地在每个渲染上分离和重新附加。
function listener() {
console.log('click');
}
function Example() {
const [count, setCount] = window.React.useState(0);
window.React.useEffect(() => {
console.log(`adding listener ${count}`);
window.addEventListener("click", listener);
return () => {
console.log(`removing listener ${count}`);
window.removeEventListener("click", listener);
};
}); // <-- because we're not passing anything here, we have an effect on each render
window.React.useEffect(() => {
setTimeout(() => {
setCount(count + 1);
}, 1000)
});
return count;
}
window.ReactDOM.render(window.React.createElement(Example), document.getElementById('root'))
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 id="root"></div>
Run Code Online (Sandbox Code Playgroud)
但是,如果您通过传入一个空数组来明确声明没有依赖关系[]
,useEffect
则只会运行一次,从而使这种模式对于事件处理程序附件来说是完全合法的。
function listener() {
console.log('click');
}
function Example() {
const [count, setCount] = window.React.useState(0);
window.React.useEffect(() => {
console.log(`adding listener ${count}`);
window.addEventListener("click", listener);
return () => {
console.log(`removing listener ${count}`);
window.removeEventListener("click", listener);
};
}, []); // <-- we can control for this effect to run only once during the lifetime of this component
window.React.useEffect(() => {
setTimeout(() => {
setCount(count + 1);
}, 1000)
});
return count;
}
window.ReactDOM.render(window.React.createElement(Example), document.getElementById('root'))
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 id="root"></div>
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
22578 次 |
最近记录: |