2019年2月,随着react16.8版本的发布,react带来了稳定版的hooks,我从2019年的10月份开始使用hook,现在使用了大半年了,记录下遇到的坑
1、useState
useState 是hook组件的状态管理,使用的方法也很简单
import React, { useState } from 'react'; const Demo = () => { const [count, setCount] = useState() return( <> <button onClick={() => { setCount(count + 1); }}> {count} </button> </> ) } export default Demo;
2、useEffect
import React, { useState, useEffect } from 'react'; const Demo = () => { const [count, setCount] = useState(); useEffect(() => { console.log('每次组件渲染的时候,我都会执行,我就是class组件的render') }) useEffect(() => { console.log('组件第一次渲染的时候,我才会执行,我就是class组件的componentdidmount'); }, []) useEffect(() => { console.log('只有count的值发生改变的时候我才会执行'); }, [count]) return( <> <button onClick={() => { setCount(count + 1); }}> {count} </button> </> ) } export default Demo;
3、useMemo
可以返回一个常量
可以返回一个方法
import React, { useState, useEffect, useMemo } from 'react'; const Demo = () => { const [count, setCount] = useState(); useEffect(() => { console.log('每次组件渲染的时候,我都会执行,我就是class组件的render') }) useEffect(() => { console.log('组件第一次渲染的时候,我才会执行,我就是class组件的componentdidmount'); }, []) useEffect(() => { console.log('只有count的值发生改变的时候我才会执行'); }, [count]) const countText = useMemo(() => { return '我是count的值:' + count }, [count]) return( <> <button onClick={() => { setCount(count + 1); }}> {count} </button> {countText} </> ) } export default Demo;
import React, { useState, useEffect, useMemo } from 'react'; const Demo = () => { const [count, setCount] = useState(); useEffect(() => { console.log('每次组件渲染的时候,我都会执行,我就是class组件的render') }) useEffect(() => { console.log('组件第一次渲染的时候,我才会执行,我就是class组件的componentdidmount'); }, []) useEffect(() => { console.log('只有count的值发生改变的时候我才会执行'); }, [count]) const countText = useMemo(() => { return '我是count的值:' + count }, [count]) const countAdd = useMemo(() => { return () => setCount(count + 1); }, [count]) return( <> <button onClick={countAdd}> {count} </button> {countText} </> ) } export default Demo;
4、useCallback
import React, { useState, useEffect, useMemo, useCallback } from 'react'; const Demo = () => { const [count, setCount] = useState(); useEffect(() => { console.log('每次组件渲染的时候,我都会执行,我就是class组件的render') }) useEffect(() => { console.log('组件第一次渲染的时候,我才会执行,我就是class组件的componentdidmount'); }, []) useEffect(() => { console.log('只有count的值发生改变的时候我才会执行'); }, [count]) const countText = useMemo(() => { return '我是count的值:' + count }, [count]) const countAdd = useMemo(() => { return () => setCount(count + 1); }, [count]) const countAdd2 = useCallback(() => { setCount(count + 1); }, [count]) return( <> <button onClick={countAdd}> {count} </button> <button onClick={countAdd2}> test </button> {countText} </> ) } export default Demo;
5、useImperativeHandle
将组件内部的方法暴露出来
1)父组件
import React, { useRef } from 'react'; import Child from './index.jsx'; const Parents = (props, ref) => { const cRef = useRef(); return ( <> <button onClick={() => { console.log(cRef.current.getData()); }}> 获取子组件的状态数据 </button> <Child ref={cRef} /> </> ) } export default Parents;
2)子组件
import React, { useState, useEffect, useMemo, useCallback, useImperativeHandle, forwardRef } from 'react'; const Demo = (props, ref) => { const [count, setCount] = useState(); useEffect(() => { console.log('每次组件渲染的时候,我都会执行,我就是class组件的render') }) useEffect(() => { console.log('组件第一次渲染的时候,我才会执行,我就是class组件的componentdidmount'); }, []) useEffect(() => { console.log('只有count的值发生改变的时候我才会执行'); }, [count]) const countText = useMemo(() => { return '我是count的值:' + count }, [count]) const countAdd = useMemo(() => { return () => setCount(count + 1); }, [count]) const countAdd2 = useCallback(() => { setCount(count + 1); }, [count]) useImperativeHandle(ref, () => ({ getData: () => { return { count } }, })); return( <> <button onClick={countAdd}> {count} </button> <button onClick={countAdd2}> test </button> {countText} </> ) } export default forwardRef(Demo);