精读React hook(十一):useInsertionEffect——CSS-in-JS样式注入新方式

React发展至今,已经不局限于前端开发框架的定位,它已经逐渐发展成框架的框架。为什么这么说呢?因为React这几年推出了很多服务于上层框架的API,这类API普通开发者一般不需要关注。在React hooks里,useInsertionEffect就是这样的定位------useInsertionEffect是为CSS-in-JS库提供的一个hook,它让后者可以更合理地注入样式,普通开发者可以不用关注useInsertionEffect

useInsertionEffect能为CSS-in-JS带来什么?

useInsertionEffect出现以前,无论是使用useEffect注入还是useLayoutEffect注入,都存在重复计算和性能浪费的问题,而像styled-components使用babel插件则又显得不够灵活。

为了弥补这些主流方案的不足,React用useInsertionEffect给CSS-in-JS库作者多一个选择,useInsertionEffect有这样的优点:

  1. 动态性:允许在运行时动态地注入样式,这使得基于组件的状态、道具或上下文的样式变化变得容易。
  2. 及时注入:保证了在任何布局效果触发之前插入样式,减少了样式的重复计算和布局抖动。

总结来说,再高度动态样式的应用中,useInsertionEffect的表现会比其它方案更优秀。

useInsertionEffect基本使用

这是基础用法的定义:

jsx 复制代码
useInsertionEffect(setup, dependencies?)

setup方法里可以做我们需要的处理,dependencies则是依赖数组,和useEffectuseLayoutEffect的依赖数组规则一样。

现在来看个详细的用法示例:

jsx 复制代码
import { useInsertionEffect } from 'react';

function useDynamicStyle(styleObj) {
  const cssString = convertStyleObjToCSS(styleObj); // 将样式对象转换为 CSS 字符串的辅助函数

  useInsertionEffect(() => {
    const styleElement = document.createElement('style');
    styleElement.innerHTML = cssString;
    document.head.appendChild(styleElement);
    return () => {
      document.head.removeChild(styleElement);
    };
  }, [cssString]);
}

useInsertionEffect里面,我们可以动态注入<style>

注意事项

  • useInsertionEffect只在客户端运行,不能在服务器渲染期间运行。
  • 不能从useInsertionEffect中更新状态。这是因为useInsertionEffect专为插入操作设计的,而不是为响应式状态变化设计的。如果在useInsertionEffect里更新状态,会造成组件重新渲染。
  • useInsertionEffect运行时,refs还没有附加。如果你试图在useInsertionEffect中访问ref,你可能会得到null或未定义的值。
  • useInsertionEffect可能在DOM更新之前或之后运行,所以不能依赖于DOM在特定时刻的更新状态。这是因为useInsertionEffect的设计初衷是在任何布局效果触发之前插入元素,但它并不保证在 DOM 的任何特定更新之前或之后运行。因此,依赖于DOM在特定时刻的状态可能导致不可预测的行为。例如:假设你希望在useInsertionEffect中检查某个元素的尺寸。但由于 DOM 可能尚未更新,所以你得到的尺寸可能是旧的或不准确的。

结语

虽然useInsertionEffect是为CSS-in-JS库提供的,但作为一名想了解React生态的开发者,即使工作中用不到useInsertionEffect,掌握一下基础知识也是有利无害。

系列文章列表

精读React hook(一):useState 的几个基础用法和进阶技巧

精读React hook(二):React状态管理的强大工具------useReducer

精读React hook(三):useContext从基础应用到性能优化

精读React hook(四):useRef的多维用途

精读React hook(五):useEffect使用细节知多少?

精读React hook(六):useLayoutEffect解决了什么问题?

精读React hook(七):用useMemo来减少性能开销

精读React hook(八):我们为什么需要useCallback

精读React hook(九):使用useTransition进行非阻塞渲染

精读React hook(十):使用useDeferredValue来做状态延迟更新

精读React hook(十一):useInsertionEffect------CSS-in-JS样式注入新方式

未完待续......

相关推荐
刘一说11 小时前
Vue 组件不必要的重新渲染问题解析:为什么子组件总在“无故”刷新?
前端·javascript·vue.js
jin12332211 小时前
基于React Native鸿蒙跨平台移动端表单类 CRUD 应用,涵盖地址列表展示、新增/编辑/删除/设为默认等核心操作
react native·react.js·ecmascript·harmonyos
徐同保12 小时前
React useRef 完全指南:在异步回调中访问最新的 props/state引言
前端·javascript·react.js
浮游本尊12 小时前
React 18.x 学习计划 - 第十三天:部署与DevOps实践
学习·react.js·状态模式
刘一说13 小时前
Vue 导航守卫未生效问题解析:为什么路由守卫不执行或逻辑失效?
前端·javascript·vue.js
一周七喜h13 小时前
在Vue3和TypeScripts中使用pinia
前端·javascript·vue.js
摘星编程13 小时前
OpenHarmony环境下React Native:DatePicker日期选择器
react native·react.js·harmonyos
weixin_3954489113 小时前
main.c_cursor_0202
前端·网络·算法
橙露13 小时前
NNG通信框架:现代分布式系统的通信解决方案与应用场景深度分析
运维·网络·tcp/ip·react.js·架构
摘星编程13 小时前
用React Native开发OpenHarmony应用:Calendar日期范围选择
javascript·react native·react.js