React Hooks 用法详解3

简介: React Hooks 用法详解

8、useLayoutEffect

语法:

useLayoutEffect(() => { doSomething });


useEffect Hooks 类似,都是执行副作用操作。但是它是在所有 DOM 更新完成后触发。可以用来执行一些与布局相关的副作用,比如获取 DOM 元素宽高,窗口滚动距离等等。

进行副作用操作时尽量优先选择 useEffect,以免阻止视觉更新。与 DOM 无关的副作用操作请使用 useEffect

用法

用法与 useEffect 类似。

Example.js

import React, { useRef, useState, useLayoutEffect } from 'react';
export default () => {
    const divRef = useRef(null);
    const [height, setHeight] = useState(100);
    useLayoutEffect(() => {
        // DOM 更新完成后打印出 div 的高度
        console.log('useLayoutEffect: ', divRef.current.clientHeight);
    })
    return <>
        <div ref={ divRef } style={{ background: 'red', height: height }}>Hello</div>
        <button onClick={ () => setHeight(height + 50) }>改变 div 高度</button>
    </>

注意:

  1. useLayoutEffect 相比 useEffect,通过同步执行状态更新可解决一些特性场景下的页面闪烁问题。
  2. useEffect 可以满足百分之99的场景,而且 useLayoutEffect 会阻塞渲染,请谨慎使用。
  3. useEffect 在全部渲染完毕后才会执行
  4. useLayoutEffect 会在 浏览器 layout 之后,painting 之前执行
  5. 其函数签名与 useEffect 相同,但它会在所有的 DOM 变更之后同步调用 effect
  6. 可以使用它来读取 DOM 布局并同步触发重渲染
  7. 在浏览器执行绘制之前 useLayoutEffect 内部的更新计划将被同步刷新
  8. 尽可能使用标准的 useEffect 以避免阻塞视图更新

9、forwardRef

因为函数组件没有实例,所以函数组件无法像类组件一样可以接收 ref 属性

function Parent() {
    return (
        <>
         // <Child ref={xxx} /> 这样是不行的
            <Child />
            <button>+</button>
        </>
    )
}
  • forwardRef 可以在父组件中操作子组件的 ref 对象
  • forwardRef 可以将父组件中的 ref 对象转发到子组件中的 dom 元素上
  • 子组件接受 props 和 ref 作为参数
function Child(props,ref){
  return (
    <input type="text" ref={ref}/>
  )
}
Child = React.forwardRef(Child);
function Parent(){
  let [number,setNumber] = useState(0);
  // 在使用类组件的时候,创建 ref 返回一个对象,该对象的 current 属性值为空
  // 只有当它被赋给某个元素的 ref 属性时,才会有值
  // 所以父组件(类组件)创建一个 ref 对象,然后传递给子组件(类组件),子组件内部有元素使用了
  // 那么父组件就可以操作子组件中的某个元素
  // 但是函数组件无法接收 ref 属性 <Child ref={xxx} /> 这样是不行的
  // 所以就需要用到 forwardRef 进行转发
  const inputRef = useRef();//{current:''}
  function getFocus(){
    inputRef.current.value = 'focus';
    inputRef.current.focus();
  }
  return (
      <>
        <Child ref={inputRef}/>
        <button onClick={()=>setNumber({number:number+1})}>+</button>
        <button onClick={getFocus}>获得焦点</button>
      </>
  )
}

10、useImperativeHandle

  • useImperativeHandle可以让你在使用 ref 时,自定义暴露给父组件的实例值,不能让父组件想干嘛就干嘛
  • 在大多数情况下,应当避免使用 ref 这样的命令式代码。useImperativeHandle 应当与 forwardRef 一起使用
  • 父组件可以使用操作子组件中的多个 ref
import React,{useState,useEffect,createRef,useRef,forwardRef,useImperativeHandle} from 'react';
function Child(props,parentRef){
    // 子组件内部自己创建 ref
    let focusRef = useRef();
    let inputRef = useRef();
    useImperativeHandle(parentRef,()=>(
      // 这个函数会返回一个对象
      // 该对象会作为父组件 current 属性的值
      // 通过这种方式,父组件可以使用操作子组件中的多个 ref
        return {
            focusRef,
            inputRef,
            name:'计数器',
            focus(){
                focusRef.current.focus();
            },
            changeText(text){
                inputRef.current.value = text;
            }
        }
    });
    return (
        <>
            <input ref={focusRef}/>
            <input ref={inputRef}/>
        </>
    )
}
Child = forwardRef(Child);
function Parent(){
  const parentRef = useRef();//{current:''}
  function getFocus(){
    parentRef.current.focus();
    // 因为子组件中没有定义这个属性,实现了保护,所以这里的代码无效
    parentRef.current.addNumber(666);
    parentRef.current.changeText('<script>alert(1)</script>');
    console.log(parentRef.current.name);
  }
  return (
      <>
        <ForwardChild ref={parentRef}/>
        <button onClick={getFocus}>获得焦点</button>
      </>
  )
}

官网介绍forwardRef与useImperativeHandle结合使用

相关文章
|
5天前
|
设计模式 存储 前端开发
React开发设计模式及原则概念问题之自定义Hooks的作用是什么,自定义Hooks设计时要遵循什么原则呢
React开发设计模式及原则概念问题之自定义Hooks的作用是什么,自定义Hooks设计时要遵循什么原则呢
|
1月前
|
前端开发 JavaScript 安全
TypeScript在React Hooks中的应用:提升React开发的类型安全与可维护性
【7月更文挑战第17天】TypeScript在React Hooks中的应用极大地提升了React应用的类型安全性和可维护性。通过为状态、依赖项和自定义Hooks指定明确的类型,开发者可以编写更加健壮、易于理解和维护的代码。随着React和TypeScript的不断发展,结合两者的优势将成为构建现代Web应用的标准做法。
|
14天前
|
前端开发 开发者
彻底颠覆!React Hooks带来前端开发的革命,你准备好了吗?
【8月更文挑战第6天】在现代Web开发中,React作为顶级前端框架,以高效性能和丰富生态著称。React Hooks自16.8版本引入,赋予函数组件使用状态和生命周期的能力,使代码更简洁、模块化,易于维护。常用Hooks如`useState`、`useEffect`等简化了状态管理和副作用操作。Hooks不仅增强了组件能力,提高了代码可读性和可维护性,还在各种应用场景中展现出强大功能,尤其是在中大型项目中优化了代码结构和提升了开发效率。总之,React Hooks为前端开发注入了新活力,推动了更高效便捷的开发实践。
26 1
|
1月前
|
前端开发
React Hooks实战技巧:提升你的组件开发效率
【7月更文挑战第16天】React Hooks为React开发带来了革命性的变化,使得函数式组件更加强大和灵活。通过掌握上述实战技巧,你可以更高效地编写清晰、可维护和可复用的React组件。希望这些技巧能帮助你在React开发之路上走得更远。
|
10天前
|
JavaScript 前端开发 API
浅谈:为啥 Vue 和 React 都选择了 Hooks?
浅谈:为啥 Vue 和 React 都选择了 Hooks?
|
1月前
|
前端开发 JavaScript 开发者
前端框架与库 - React生命周期与Hooks
【7月更文挑战第13天】React 框架革新UI构建,引入Hooks简化组件状态管理和副作用处理。组件生命周期涉及挂载、更新、卸载,对应不同方法,如`componentDidMount`、`shouldComponentUpdate`等,但现在推荐使用`useState`和`useEffect` Hooks。`useEffect`处理副作用,需注意清理和依赖数组。避免问题的关键在于正确使用Hooks和理解其工作模式,以构建高效应用。
|
1月前
|
前端开发 JavaScript 数据格式
react18【系列实用教程】Hooks (useState,useReducer,useRef,useEffect,useContext,useMemo,useCallback,自定义 Hook )
react18【系列实用教程】Hooks (useState,useReducer,useRef,useEffect,useContext,useMemo,useCallback,自定义 Hook )
40 1
|
1月前
|
缓存 前端开发 JavaScript
React Hooks(实例及详解)
【7月更文挑战第2天】React Hooks(实例及详解)
33 3
|
1月前
|
存储 前端开发 JavaScript
react hooks 学习进阶
【7月更文挑战第12天】 React Hooks(自16.8版起)让函数组件能处理状态和副作用。useState用于添加状态管理,useEffect处理副作用,useContext共享数据,useReducer处理复杂状态逻辑,useRef获取引用。进阶技巧涉及性能优化,如useMemo和useCallback,以及遵循规则避免在不适当位置调用Hooks。理解异步更新机制和结合Redux等库提升应用复杂性管理。持续学习新技巧是关键。
30 0
|
1月前
|
前端开发
react18【系列实用教程】Hooks 闭包陷阱 (2024最新版)含useState 闭包陷阱,useEffect 闭包陷阱,useCallback 闭包陷阱
react18【系列实用教程】Hooks 闭包陷阱 (2024最新版)含useState 闭包陷阱,useEffect 闭包陷阱,useCallback 闭包陷阱
28 0

热门文章

最新文章