P F*_*ter 6 reactjs react-hooks
我已经看到了这个答案:useMemo vs. useEffect + useState,它总结起来很不错useEffect,但就我而言,我想执行一个昂贵的操作,该操作将尽早更改DOM。将useMemo()仍然被代替的建议useLayoutEffect()与状态更新?效果的双重渲染->状态更新会否提高性能?
编辑
useLayoutEffect() 场景:
useLayoutEffect(() => {
const tokens = expensiveOperationGeneratingClasses(param1)
setTokens(tokens)
},
[param1])
render (
<>
{
tokens.map(token => <span className={token.id}/>)
}
</>
)
Run Code Online (Sandbox Code Playgroud)
useMemo 场景:
const tokens = useMemo(() => {
return expensiveOperationGeneratingClasses(param1)
},
[param1]
render (
<>
{
tokens.map(token => <span className={token.id}/>)
}
</>
)
Run Code Online (Sandbox Code Playgroud)
实际上,我意识到我不是在进行DOM操作,而是在呈现<span>标记之前生成类名以避免闪烁,所以我认为我最好使用useMemo,对吗?
我将尝试解释在哪里可以使用 LayoutEffect 和 Memo。让我们从 LayoutEffect 的使用开始。
Dan Abramov Link 1、Link 2表示,使用 LayoutEffect 有一些缺点。Kent C很好地解释了在哪里可以使用这些。Dodds。如果您需要示例,可以在这里查看Chris。不要忘记阅读以了解差异。
现在介绍一下 Memo 的使用。它也有一个缺点。对于我们使用 Memo 的内容以及使用它的位置,您可以在这里找到。
现在正在实践中。
选项 1 使用 LayoutEffect
import React, { useState, useLayoutEffect } from "react";
import ReactDOM from "react-dom";
import "./styles.css";
const Control = () => {
const [add, setAdd] = useState(1);
return (
<div>
<div>
<PostOffice add={add} />
</div>
<div onClick={() => setAdd(add + 1)}>{"Click"}</div>
</div>
);
};
function PostOffice({ add }) {
const [letter, setLetter] = useState(add);
useLayoutEffect(() => {
console.log("useLayoutEffect");
setLetter(add);
}, [add]);
console.log(letter);
return <div className="App">{console.log(letter, "DOM")}</div>;
}
const rootElement = document.getElementById("root");
ReactDOM.render(<Control />, rootElement);
Run Code Online (Sandbox Code Playgroud)
我不确定这个选项1,因为这里有一个反模式效果。
选项 2 使用 LayoutEffect
import React, { useState, useLayoutEffect } from "react";
import ReactDOM from "react-dom";
import "./styles.css";
const Control = () => {
const [add, setAdd] = useState(1);
return (
<div>
<div>
<PostOffice add={add} />
</div>
<div onClick={() => setAdd(add + 1)}>{"Click"}</div>
</div>
);
};
function PostOffice({ add }) {
const [letter, setLetter] = useState(0);
useLayoutEffect(() => {
console.log("useLayoutEffect");
setLetter(add);
}, [add]);
console.log(letter);
return <div className="App">{console.log(letter, "DOM")}</div>;
}
const rootElement = document.getElementById("root");
ReactDOM.render(<Control />, rootElement);
Run Code Online (Sandbox Code Playgroud)
会有无意义的渲染
选项 useMemo
import React, { useState, useMemo } from "react";
import ReactDOM from "react-dom";
import "./styles.css";
const Control = () => {
const [add, setAdd] = useState(1);
return (
<div>
<div>
<PostOffice add={add} />
</div>
<div onClick={() => setAdd(add + 1)}>{"Click"}</div>
</div>
);
};
function PostOffice({ add }) {
const Letter = useMemo(() => {
console.log("useMemo");
return add + 1;
}, [add]);
console.log(Letter);
return <div className="App">{console.log(Letter, "DOM")}</div>;
}
const rootElement = document.getElementById("root");
ReactDOM.render(<Control />, rootElement);
Run Code Online (Sandbox Code Playgroud)
这里一切都很完美
全部的
减去 useMemo 1,
减去 useLayoutEffect, 1,反模式效果或无意义渲染,添加 useState,
这就是为什么你应该使用 useMemo。
但如果有办法不使用这些钩子那就完美了。
| 归档时间: |
|
| 查看次数: |
401 次 |
| 最近记录: |