首页 > 解决方案 > React Functional Component - 在 const vs state 中存储一些 prop 计算

问题描述

我有一个只渲染一次然后被销毁的组件,我已经实现了“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>
}

我的问题是:

就最佳实践/“反应方式”而言,最佳解决方案是什么?

每个实施如何影响性能

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

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

谢谢!

标签: javascriptreactjsreact-hooksuse-statereact-functional-component

解决方案


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

如果计算很昂贵,推荐的处理方法是hook useMemo就像你的Comp4例子一样。但是,您需要确保num在您的依赖数组中包含输入变量,以便在更改numAsStr时重新计算。num例如:

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

useState像你一样使用Comp2只会numToStr在初始渲染中运行,所以如果你num改变了,你会得到陈旧的值。

useEffect如您所见,使用Comp3引入了不必要的双重渲染 - 例如,它首先渲染没有值numAsStr,然后再次渲染。

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


推荐阅读