不要使用使用效果
#javascript #react #前端 #hooks

在这篇文章中,我们将证明在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将在此序列中渲​​染此组件:

  1. 阅读prop 名称 ,假设它的价值是 “ John Doe”
  2. 定义称为 首字母 的状态,并将其作为初始值。
  3. 用此初始值返回JSX,因此 缩写 将是 空字符串
  4. 运行传递到使用效果钩的功能,该钩将名称设置为 “ John Doe”
  5. 返回现在具有 首字母 的新JSX AS JD

因此,我们的组件已经具有值 “ John Doe” 从头开始,但是使用效果使其呈现两次! ...让我们摆脱这种额外的渲染...

const User = ({name}) => { // 1
  const initials = name.split(" ").map(str => str.charAt(0)); // 2
  return (
    <p>{initials}</p> // 3
  );
};

现在反应

  1. 阅读 名称的值
  2. 计算 首字母
  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)时才使用使用效率

谢谢你!