在这篇文章中,我们将证明在90%的组件中,我们不需要编写使用效果...
第一个问题,使用效果何时运行?
const User = ({name}) => { // 1
const [initials, setInitials] = useState(""); // 2
useEffect(() => {
setInitials(name.split(" ").map(str => str.charAt(0))); // 4
}, [name]);
return (
<p>{initials}</p> // 3
);
};
React将在此序列中渲染此组件:
- 阅读prop 名称 ,假设它的价值是 “ John Doe” 。 。
- 定义称为 首字母 的状态,并将其作为初始值。
- 用此初始值返回JSX,因此 缩写 将是 空字符串 。
- 运行传递到使用效果钩的功能,该钩将名称设置为 “ John Doe”
- 返回现在具有 首字母 的新JSX AS JD
因此,我们的组件已经具有值 “ John Doe” 从头开始,但是使用效果使其呈现两次! ...让我们摆脱这种额外的渲染...
const User = ({name}) => { // 1
const initials = name.split(" ").map(str => str.charAt(0)); // 2
return (
<p>{initials}</p> // 3
);
};
现在反应
- 阅读 名称的值
- 计算 首字母
- 以正确的值返回JSX,而无需再次渲染组件!
如果先前的组件由于其他道具的变化而具有更多的渲染效果,它将重新计算每个新渲染中的缩写,对吗?是的,但是不要使用使用效果并将名称放在依赖项数组中...我们可以轻松地使用UseMemo Hook不用每个新渲染来重新计算值!
const User = ({name, age, email}) => { // 1
const initials = useMemo(() => {
name.split(" ").map(str => str.charAt(0)); // 2
}, [name]);
return (
<p>{initials}</p> // 3
);
};
当年龄或电子邮件更改时,组件不会重新计算首字母缩写!
因此,每当我们创建一个反应组件时,让我们将此规则放在脑海中...
任何可以从道具或状态计算的任何东西,不应在使用效率
内计算
我们都滥用了使用效果挂钩,以实现可以轻松实现的事物,而无需使用额外的渲染器来降低页面性能。
只有一种情况,您必须使用使用效果,如果您想在组件安装时做某事(首次显示),此内容是外部的(api提取,订阅事件,将某物应用于DOM元素),只是不依赖于状态或道具...所以它会像这样
useEffect(() => {
const fetchedPosts = fetch('....');
}, [])
结论
- 使用效应应该是您的最后选择
- 使用效果运行渲染后您的组件,因此,如果对状态进行任何更改,它将导致其他渲染
- 任何可以根据道具或状态计算的任何东西,不应在使用效率内计算出来
- 您可以将USEMEMO用于昂贵的计算
- 您只能在要执行外部(ex:api fetch)时才使用使用效率
谢谢你!