关于react|关于react hooks的一些Q&A
问题:props、setState导致的组件重新渲染,宏观上是怎么样的?
比如有如下代码:
const component = (props) => {
const [a, setA] = useState(true);
const [b, setB] = useState(true);
const ref = useRef(true);
const fn = useCallback(() => {}, [a]);
const memo = useMemo(() => {}, [b]);
useEffect(() => {
setA(false);
}, [b]);
return ({a}
{props.c})
}
每一次组件的重新渲染,都会有链表(假设这个链表叫link1)依次记录useState -> useState -> useRef -> useCallback -> useMemo -> useEffect
每一个的区别,详细要看每一个的解析。这里只简述deps对函数运行与否的影响。
这里的deps会被记录link1中。第二次渲染组件开始,会对deps比对,如果deps不同,就会执行对应方法。
比如fn = useCallback这里,第一次渲染组件,把方法赋值给了fn,记录[a]的值
【关于react|关于react hooks的一些Q&A】第二次渲染组件开始,会查看[a]的值是否更新了(示例代码中是更新了,因为useEffect),如果更新了,就会把useCallback里的第一个参数重新赋值给fn。
问题:useMemo和useEffect的区别是什么? 不同点如下:
- useMemo是渲染过程中执行,而useEffect是在渲染之后,重新搞一个渲染队列执行
- 因为1的原因,会导致在useMemo的第一个参数方法里,如果调用了set...State方法,会报错。但是在useEffect里不会,但是如果在useEffect里这么做了,会触发重新渲染。如果重新渲染的值在useEffect的deps里,那么就造成了循环渲染,最后也会报错。
- 用法上,useMemo一般会直接给一个值赋值,因为第一个参数方法会有返回值。而useEffect没有返回值。
情况1:涉及的变量都是useState创建的变量 这种情况很显然是不行的,因为如果我们调用了set...State,而deps中没有更新后的数据,那么这三个use返回的内容会完全不符合预期
所以,不行。
情况2:涉及的变量是useRef创建的 useRef创建意味着一直不会更新这个值,除非强行用ref.current修改。
但是用ref.current更新的话,也不会触发这三个use方法。所以,这个是可以不放deps里的。
情况3:涉及的变量是直接创建的 比如直接用
const a = initValue;
直接创建的变量,每次更新组件都会重新初始化变量。
原则上不建议这么创建变量。
这个的答案是:不要这么创建变量。
如果硬要这么创建,答案是,这个变量每次都会初始化,之后这个变量的改变也不会引发三个use的重新创建。
推荐阅读
- 关于@Query注解的用法(Spring|关于@Query注解的用法(Spring Data JPA)
- react|react hooks源码核心(ReactCurrentDispatcher)
- react|react hooks核心(hooktype和ReactCurrentDispatcher)
- react|react hooks 本质探索 - useMemo、useEffect源码解析
- 关于Mybatis动态sql中test的坑点总结
- python爬虫|关于使用python 动态爬虫Selenium 下载文件,文件类型的设置
- react的”Hello|react的”Hello World !“
- React内部的性能优化没有达到极致()
- react函数组件使用React.memo避免重复渲染
- 【C语言】指针详解