【问题标题】:Rerender only specific Child Components in JSX map function在 JSX 映射函数中仅重新渲染特定的子组件
【发布时间】:2020-11-30 13:34:58
【问题描述】:

我正在通过一个数组进行映射,该数组为数组中的每个项目返回 JSX 组件。在运行时我想传递值。如果它们与单个项目的值匹配,则它们的单个组件会被修改。

我正在尝试找到一种方法来实现这一点,而无需重新渲染所有组件,目前发生这种情况是因为道具发生了变化

我曾尝试在类组件中使用 shouldComponentUpdate,但似乎这样我只能将 prevState 和 prevProps 与相应的更改进行比较。我在 Map 函数中进一步考虑了 useMemo,但它不起作用,因为它嵌套在 map 函数中。

const toParent=[1,2,4,5]

父组件:

function parent({ toParent }) {

const [myNumbers] = useState([1,2,3,4, ..., 1000]);

return (
   <div>
      {myNumbers.map((number, index) => (
         <Child toChild = { toParent } number = { number } 
          index= { index } key = { number }/>
      ))}
   </div>
  )
}

子组件:

function Child({toChild, number, index}){
   const [result, setResult] = useState(() => { return number*index }

   useEffect(()=> {
      if (toChild.includes(number)) {
         let offset = 10
         setResult((prev)=> { return { prev+offset }})
      }
   }, [toChild])

   return ( 
      <div style={{width: result}}> Generic Div </div> )
}

【问题讨论】:

  • 你可以使用 React.memo。 useMemo 用于记忆值而不是用于组件。 React.memo 是一个 HOC,类似于 shouldComponentUpdate
  • 我也使用过 React.Memo,但我不知道如何在不创建无限循环的情况下比较两个属性,就像我的情况一样
  • React.memo 高阶组件是您如何将传入的道具和“建议”与反应框架进行比较以重新渲染。 memo HOC 不会导致任何无限循环,因为它不会更新状态或道具。
  • 阅读文档是一个很好的起点:reactjs.org/docs/react-api.html#reactmemo,使用第二个参数,一个自定义比较函数,它接受前一个下一个道具。不过请注意,比较函数本质上会返回shouldComponentUpdate相反
  • 如果“发布我的解决方案”是指对某个问题的回答,那么是的,当然。

标签: javascript reactjs map-function rerender react-memo


【解决方案1】:

我的问题的解决方案是使用 React.memo HOC 并比较属性彼此并将其导出为React.memo(Child, propsAreEqual)

性能

这样可以避免使用 findElementbyId(在任何情况下都不推荐)和 shouldComponentUpdate 等其他方法来定位地图函数中的特定项目。 性能也相当不错。使用这种方法可以将渲染时间从每 250ms 的 40ms 减少到大约 2ms​​。

实施

在子组件中:

function Child(){...}
function propsAreEqual(prev, next) {
   //returning false will update component, note here that nextKey.number never changes.
   //It is only constantly passed by props
    return !next.toChild.includes(next.number)

}
export default React.memo(Child, propsAreEqual);

或者,如果还应检查其他语句:

function Child(){...}
function propsAreEqual(prev, next) {

   if (next.toChild.includes(next.number)) { return false }
   else if ( next.anotherProperty === next.someStaticProperty ) { return false }
   else { return true }
  }

export default React.memo(Key, propsAreEqual);

【讨论】:

  • Key 来自哪里?React.memo(Key, propsAreEqual);
猜你喜欢
  • 2021-04-22
  • 1970-01-01
  • 2021-08-08
  • 1970-01-01
  • 2022-01-25
  • 1970-01-01
  • 1970-01-01
  • 2019-06-01
  • 1970-01-01
相关资源
最近更新 更多