React Hooks 初上手

  • Post author:
  • Post category:其他




React Hooks 初上手



为什么要用hooks
  1. Hook是React16.8的新增特性
  2. 编写class组件逻辑比较简单,但是业务增多,class组件就会越来越复杂(hook解耦性更强)
  3. 繁琐的生命周期代替


了解项目中常用的hooks
  1. useState
	const [state, setState] = useState(initialState);
	// 需要传入一个参数作为状态的初始值,当函数执行后会返回两个值,一个是当前状态的属性,一个是修改状态的方法。
	// 值的改变能驱动视图的更新,但只能通过setState 赋值
	// 有点像 vue3 的 const state = ref(0)
	
	// setState 是对原有值的覆盖 所以每次都以赋值的形式
	const [state, setState] = useState({a:1,b:2}); 
	setState((pre)=>{
		return {
			...pre,
			b: 45,
		}
	})
	//(setState是异步执行 也不接受await)

  1. useEffect

    (最难理解的钩子)

    该 Hook 接收一个包含命令式、且可能有

    副作用

    代码的函数
	//对一个值的副作用作为依赖监听 当 count 变化时就会触发副作用
	const [count, setCount] = useState(0)
	useEffect(() => {
	    console.log("useEffect:", count)
	},[count])
	
	//可以对多个值进行依赖监听
	const [count, setCount] = useState(0)
	const [state, setState] = useState({a:1,b:2})
	useEffect(() => {
	    console.log("useEffect:", count,state)
	},[count,state.a])
	
	//代替生命周期 数组为空组件初始化只会触发一次 ,return的函数组件销毁的时候触发,一般用于清除定时器等
	const getList = async () => {
		await axios
	}
	useEffect(() => {
	    getList()
	    const timeInterval = setInterval(()=>{
	    	console.log('react真难用')
	    },3000)
	    return ()=>{
	    	clearInterval(timeInterval)
	    }
	},[])

注意:

1. 添加错误的依赖会造成重复的执行副作用。2. 副作用内不能重新赋值造成无限循环。

useEffect的依赖数组是最容易造成报错的原因。

  1. useCallback
	//传入一个回调函数,依赖更新才会返回一个新的函数
	const memoizedCallback = useCallback(
	  () => {
	    doSomething(a, b);
	  },
	  [a, b],
	);

用的比较少,也很容易出现bug,主要用在性能优化

  1. useMemo

    (计算属性类似vue2 computed)
	const [count, setCount] = useState(1)
	//useMemo通过对依赖的计算 返回一个值
	const moreCount = useMemo(() => {
		return count + 100
	},[count])
	//useMemo也可以通过对依赖的计算返回一个函数(类似useCallback)
	const fnCount = useMemo(() => {
		return ()=>{
			if(count == 1){
				console.log('react真好用')
			}else{
				console.log('react真难用')
			}
		}
	},[count])

如果没有提供依赖项数组,useMemo 在每次渲染时都会计算新的值。

  1. useRef、forwardRef、useImperativeHandle

    可以获取元素真实节点或者组件的实例 类似 Vue2的 this,$refs.AFormRef
	// useRef + forwardRef 自定义组件这两个必须一起用
	//parent.jsx
	const AFormRef = useRef();
	......
	<AForm ref={AFormRef} {...formProps} />
	
	//forwardRef导出的组件可以通过useRef拿到 但只有dom
	//child.jsx
	React.forwardRef(function AForm(props, ref) {
	  return (
	    <div ref={ref}> 
	      <Form form={form} {...formLayout}>
	        {initFromItem()}
	      </Form>
	    </div>
	  );
	})
	// useRef + forwardRef + useImperativeHandle
	//parent.jsx
	const AFormRef = useRef();
	......
	<AForm ref={AFormRef} {...formProps} />
	//child.jsx
	React.forwardRef(function AForm(props, ref) {
	  const formRef = useRef();
	  useImperativeHandle(ref, () => ({
	    getForm: () => {
	      return 123
	    },
	    formRef:formRef,
	  }))
	  return (
	    <div ref={ref}> 
	      <Form ref={formRef} form={form} {...formLayout}>
	        {initFromItem()}
	      </Form>
	    </div>
	  );
	})	

一般获取子组件组件实例和它的方法、或者dom节点。



非常见、用的少的hooks
  1. useContext + createContext 爷爷组件向孙子组件传值
  2. useReducer 组件内用的 redux
  3. useLayoutEffect 所有的 DOM 变更之后同步调用

    (慎用容易阻塞视觉更新)
  4. useDebugValue 可用于在 React 开发者工具中显示自定义 hook 的标签。



版权声明:本文为weixin_44701229原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。