具有如此简单的反应成分:
import React, { FunctionComponent, useEffect, useState } from 'react';
export function useMediaQuery(query:string) {
console.log("useMediaQuery")
useEffect(() => {
console.log("useEffect outer")
// ...
});
}
const Sidebar: FunctionComponent = () => {
const istoBeHidden = useMediaQuery('(min-width: 700px)')
console.log("returned from useMediaQuery")
useEffect(() => console.log("useEffect inner"))
return (
<div>
<p>Sidebar</p>
{/* <button onClick={myFunction}>Click me</button> */}
</div>
)
};
export {Sidebar}我在控制台中得到以下输出:
useMediaQuery
从useMediaQuery回来
useEffect外
useEffect内部
我的问题是,为什么在从useEffect outer函数返回后调用useMediaQuery (为什么在returned from useMediaQuery行之后出现行useEffect outer )?
发布于 2022-02-10 11:57:11
我们需要一点背景知识来理解它为什么会这样。
众所周知,React使用JSX,它生成DOM的表示。这意味着每次响应决定更新时,都会调用所有函数来生成它。在此之后,又进行了另一步,并对所有效果进行了评估。效果保证在呈现后运行。
现在,回到你的案子。在第一阶段,响应调用你的边栏函数。它中的所有函数都会被执行,因此您可以在控制台中看到日志。之后,提交更改并调用效果。这就是为什么你会在最后看到效果的日志。
发布于 2022-02-10 12:59:27
useMediaQuery是一个功能组件内部的钩子。自定义钩子只是一种将某些逻辑封装到函数中的方法,该函数可能/可能不使用状态。
自定义钩子代码在每个呈现上运行。但是,您不能期望钩子运行它的所有useEffects和get与。自定义钩子中的useEffect就像任何useEffect一样,它将基于它的依赖数组运行。
它没有依赖数组,所以每次出现呈现时都会调用它,每次组件重发时都会发生这种情况。
function useMediaQuery(query) {
console.log("useMediaQuery")
React.useEffect(() => {
console.log("useEffect outer")
});
}
function App() {
const istoBeHidden = useMediaQuery('(min-width: 700px)');
const [count,setCount] = React.useState(0);
console.log("returned from useMediaQuery",count)
React.useEffect(() => console.log("useEffect inner"))
return (<div><button onClick={() => setCount(count => count+1)}>Sidebar</button></div>);
};
ReactDOM.render(<App />, document.getElementById('root'));<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.13.1/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.13.1/umd/react-dom.production.min.js"></script>
<div id="root"></div>
https://stackoverflow.com/questions/71064376
复制相似问题