React Functional Component - 在 const vs state 中存储一些 prop 计算

Posted

技术标签:

【中文标题】React Functional Component - 在 const vs state 中存储一些 prop 计算【英文标题】:React Functional Component - Store some prop calculation in const vs state 【发布时间】:2021-12-12 23:16:09 【问题描述】:

我有一个只渲染一次然后被销毁的组件, 我已经实现了“Comp3”方式。

使用“useEffect”以我收到的 num 值作为道具来计算 str,然后使用“useEffect”设置器存储结果以便在 html 中使用结果。

//Let say this function is inside the functional component
function numToStr(num:number):string
  switch(num)
    case 1:
      return "One";
    case 2:
      return "Two";
    ...
  

function Comp1(num:number)
  const numAsStr = numToStr(num);
  return <span>numAsStr</span>

function Comp2(num:number)
  const [numAsStr] = useState(numToStr(num));
  return <span>numAsStr</span>

function Comp3(num:number)
  const [numAsStr,setNumAsStr] = useState();
  useEffect(()=>
    setNumAsStr(numToStr(num));
  ,[])
  return <span>numAsStr</span>

function Comp4(num:number)
  const numAsStr = useMemo(()=>numToStr(num),[]);
  return <span>numAsStr</span>

我的问题是:

best-practice/“react-way”而言,最佳解决方案是什么?

每个实施如何影响性能

我知道组件只渲染一次这一事实是否会影响我选择实现的方式?

或者我应该把这个组件当作我不知道它应该渲染一次并且在这种情况下仍然支持“监视”正在更改的道具的选项吗? (将其添加到 useEffect / useMemo 数组中)

谢谢!

【问题讨论】:

为什么要把事情复杂化,const Comp1 = ( num ) =&gt; &lt;span&gt;numToStr(num)&lt;/span&gt;; 将它存储在状态中没有任何好处,并且绝对不会在效果中设置该状态。状态是随时间变化的值。这不符合那个描述。 我的计算功能与我在这里展示的不同..所以它并不是“过于复杂”,我试图了解我可能正在处理的最佳实践 + 性能问题 【参考方案1】:

如果strToNum 进行的计算很便宜(就像在您的简化示例中一样),那么Comp1 中的方法可能是最好和最简单的。它们会在每次组件重新渲染时运行,因此它们始终是最新的。

如果计算成本很高,推荐的处理方法是the useMemo hook,就像在您的Comp4 示例中一样。但是,您需要确保在您的从属数组中包含 num 输入变量,以便在 num 更改时重新计算 numAsStr。例如:

function Comp4(num:number)
  const numAsStr = useMemo(()=>numToStr(num),[num]);
  return <span>numAsStr</span>

像在Comp2 中一样使用useState 只会在初始渲染中运行numToStr,因此如果num 发生更改,您将获得陈旧的值。

Comp3 那样使用 useEffect 会引入不必要的双重渲染 - 例如它首先呈现没有numAsStr 的值,然后再次呈现。

我知道你说过你目前确定它不会再重新渲染 - 所以上面提到的一些缺点/陷阱可能不适用于这种情况(然后我会选择 Comp1 方法,因为它更简单)但根据我的经验,最好不要做出这样的假设——你(或队友)会在一个月内尝试重构某些东西时记住这一点吗?

【讨论】:

感谢您的详细解释!这些组件是否有最佳实践/反应方式?还是每个案件都应该区别对待? 很高兴能帮上忙!如果您对我的回答解决了您的问题感到满意,您介意点击答案旁边的复选框将其标记为“已接受”吗?这可以帮助其他人知道您认为答案是正确的,并且这是说“谢谢”的好方法:-) Re: 是否有“最佳实践” - 我的经验法则是以保持简单(例如 Comp1)为基准,使用 useMemo 优化昂贵的计算,达到useEffect 进行异步处理(例如数据获取),而useState 仅用于真正的状态(例如它们不能从其他任何东西派生)。 这是一篇更深入的好文章:kentcdodds.com/blog/dont-sync-state-derive-it 在处理完答案并再次查看我的代码后,我提出了一个相关问题.. 而不是使用 useState,我可以在组件中声明一个 let 变量并使用“useEffect”重新分配它我想要的时间。为什么我会使用“useState”钩子?

以上是关于React Functional Component - 在 const vs state 中存储一些 prop 计算的主要内容,如果未能解决你的问题,请参考以下文章

[React] Return a list of elements from a functional component in React

[React] Refactor a Stateful List Component to a Functional Component with React PowerPlug

[React 进阶系列] Functional Component 与 Class Component 中使用 Context

[React 进阶系列] Functional Component 与 Class Component 中使用 Context

[React 进阶系列] Functional Component 与 Class Component 中使用 Context

如何使用 React js 中的上下文将函数从 FUNCTIONAL 传递给 CLASS 组件并在渲染之外(没有 prop)访问它?