react教程,如何使用useInsertionEffect附加第三方css文件?
发布于 作者:苏南大叔 来源:程序如此灵动~本篇文章中,苏南大叔描述另外一个非常非常非常没用非常鸡肋的react
函数useInsertionEffect()
。基本上没啥用,官方描述上来说,是用来挂载第三方的css
和js
的,语焉不详。那么,这个超级鸡肋的react
函数useInsertionEffect()
是怎么使用的呢?这就是本文的主要话题。
苏南大叔的程序如此灵动博客,记录苏南大叔和计算机代码的故事。本文测试环境:create-react-app@5.0.1
,react@18.2.0
,react-dom@18.2.0
,node@16.14.2
。
官方描述
react
官方对这个函数也不推荐使用,推荐使用useEffect
或者useLayoutEffect
代替。
该签名与 useEffect 相同,但它在所有 DOM 突变之前同步触发。使用它在读取 useLayoutEffect 中的布局之前将样式注入 DOM。由于这个 hook 的作用域有限,所以这个 hook 不能访问 refs,也不能安排更新。
useInsertionEffect 应仅限于 css-in-js 库作者使用。优先考虑使用 useEffect 或 useLayoutEffect 来替代。
这些文字描述比较的令人费解,暂时就这么放着吧,大家慢慢体会。先看看苏南大叔根据网上的只言片语修复的功能。本文对这个useInsertionEffect()
的理解也不够深刻到位。由于这个函数的鸡肋性,就先这么看看吧。
核心代码
根据目前网上的一些只言片语,苏南大叔调试了一段代码,实现了官方所描述的这个加载第三方css
(js
文件)的功能。
加载css
文件:
let insertCSS = new Set();
function useCSS(file_name) {
useInsertionEffect(() => {
if (!insertCSS.has(file_name)) {
var _css = document.createElement("link");
_css.rel = "stylesheet";
_css.href = file_name + ".css";
document.head.appendChild(_css);
insertCSS.add(file_name);
}
});
}
加载js
文件:
let insertJS = new Set();
function useJS(file_name) {
useInsertionEffect(() => {
if (!insertJS.has(file_name)) {
var _js = document.createElement("script");
_js.type = "application/x-javascript";
_js.src = file_name + ".js";
document.head.appendChild(_js);
insertJS.add(file_name);
}
});
}
第三方文件范例
public/sunan.css
:
.sunan-class {
font-size: 22px;
color: red;
}
.sunan-class-2 {
font-size: 22px;
color: blue;
}
public/sunan.js
:
function test(){
alert("苏南大叔 测试!");
}
如何调用外部代码
定义了两个div
,应用了第三方样式表里面的定义。然后,一个调用react
自身的test()
,另外一个调用第三方的test()
函数。
<div className="sunan-class" onClick={() => { window.test() }}>调用传统第三方库的css</div>
<div className="sunan-class-2" onClick={test.bind()}>调用传统第三方库的css</div>
相比较传统的html
写法,
- 这里的
onclick
中的click
首字母是大写。否则报错。 - 调用第三方函数,不能直接写函数名,要加个
window.
,然后再包个匿名函数()=>{}
。最后放在react
的onClick={}
里面,否则也各种报错函数未定义。
参考文档:
https://newsn.net/say/react-connect-html.html
完整代码
src/App.js
:
import React, { useInsertionEffect } from "react";
const App = () => {
useCSS("sunan");
useJS("sunan");
const test = () => {
alert("react 测试!");
}
return (
<>
<div className="sunan-class" onClick={() => { window.test() }}>调用传统第三方库的css</div>
<div className="sunan-class-2" onClick={test.bind()}>调用传统第三方库的css</div>
</>
);
}
export default App;
let insertCSS = new Set();
function useCSS(file_name) {
useInsertionEffect(() => {
if (!insertCSS.has(file_name)) {
var _css = document.createElement("link");
_css.rel = "stylesheet";
_css.href = file_name + ".css";
document.head.appendChild(_css);
insertCSS.add(file_name);
}
});
}
let insertJS = new Set();
function useJS(file_name) {
useInsertionEffect(() => {
if (!insertJS.has(file_name)) {
var _js = document.createElement("script");
_js.type = "application/x-javascript";
_js.src = file_name + ".js";
document.head.appendChild(_js);
insertJS.add(file_name);
}
});
}
执行顺序
目前已经范例过三个Effect
了,分别是:useEffect()
、useLayoutEffect()
以及本文的useInsertionEffect()
。官方其实都推荐使用useEffect()
(那为啥还非要出后面这两个呢)。
useInsertionEffect
的执行时机被描述为“所有 DOM 突变之前同步触发”。下面来打印一下三者的执行时间:
React.useEffect(() => {
console.log('useEffect', performance.now().toFixed(0))
})
React.useLayoutEffect(() => {
console.log('useLayoutEffect', performance.now().toFixed(0))
})
React.useInsertionEffect(() => {
console.log('useInsertionEffect', performance.now().toFixed(0))
})
可见三者执行顺序是:useInsertionEffect()
早于useLayoutEffect()
早于useEffect()
。
而且,可以发现:StrictMode
引发的两次渲染,也并不会触发useInsertionEffect
(即使后面不添加任何,[]
字样)。这个倒是个意外...
第二个例子
这里有另外一个css-in-js
技术的例子,参考代码:
import React from 'react';
export const UseInsertion = () => {
React.useInsertionEffect(() => {
const style = document.createElement('style')
style.innerHTML = `
.css-in-js{
color: blue;
font-size: 20px;
}
`
document.head.appendChild(style)
}, [])
return (
<>
<div className="css-in-js">苏南大叔</div>
</>
);
};
useInsertionEffect()
也有第二个参数,也可以不填,或者填[]
或者监控一些变量。这个很好理解,和已知的useEffect()
规则一样,就仅仅是执行时机不同罢了。
第三个例子
styled-components
这个最经典的css-in-js
框架,里面也使用了useInsertionEffect()
。大家可以去研究一下相关代码,截图如下:
参考文字:
相关链接
- https://newsn.net/say/react-useeffect.html
- https://newsn.net/say/react-uselayouteffect.html
- https://newsn.net/say/react-useinsertioneffect.html
- https://github.com/styled-components/styled-components
结束语
更多react
相关经验文章,请点击:
本博客不欢迎:各种镜像采集行为。请尊重原创文章内容,转载请保留作者链接。