我是否可以在父功能组件中定义一个函数,以使接受该功能作为道具的子PureComponent不会重新呈现?

问题描述 投票:0回答:1

我有一个功能组件,可呈现简单子组件的集合。父组件具有更新状态的功能,并传递给子组件。由于一些性能问题,我决定将子组件变成纯组件,以减少重新渲染的数量。不幸的是,由于功能是在父功能组件中定义的,因此每当状态更新并重新渲染父功能时,都会重新定义该功能。这使子组件认为传递的函数是新函数,并且无条件地导致重新渲染。

我已经对这个问题有两种单独的解决方案,但我认为两者都不太雅致。

在我的第一个解决方案中,我将子组件变成了基于类的常规组件,并定义了一个自定义shouldComponentUpdate来基本上只忽略函数prop。这不是理想的,因为此用例实际上应该由重组包中的PureComponentpure处理。

在第二个解决方案中,我使父组件成为基于类的组件,并定义了要作为原型方法传递给我的函数。但是,我一直试图避开基于类的组件。

这是我想作为功能组件重新创建的基于类的代码:

class Parent extends Component {
  state = {
    children: [1, 2, 3, 4] // populated by an api normally
    selectedChildren: []
  };

  handleChildClick = childId => {
    // adds or removes childId from this.state.selectedChildren
    // based on if it's already in the array or not
  };

  render() {
    const children = this.state.children.map((child) => (
      <Child
        key={child}
        id={child}
        onClick={this.handleChildClick}
        selected={this.state.selectedChildren.includes(child)}
      />
    ))

    return (
      <div>
        {children}
      </div>
    );
  }
}

我想知道是否存在与上述代码等效的功能组件,请记住,子代是纯组件,仅当传递给它们的道具发生更改时才应重新渲染。

reactjs react-component rerender
1个回答
0
投票

事实证明,有一个名为useCallback的钩子,可用于在将该函数传递给子组件之前对其进行记忆。由于该函数已被记忆,因此如果函数不变,则相等比较将返回true。问题中的代码将像这样被简单地重写:

const Parent = () => {
  const [children, setChildren] = useState([1, 2, 3, 4])
  const [selectedChildren, setSelectedChildren] = useState([])

  const handleChildClick = useCallback(
    childId => {
      // adds or removes childId from selectedChildren state
      // based on if it's already in the array or not
    },
    []
  )

  const childComponents = children.map((child) => (
    <Child
      key={child}
      id={child}
      onClick={handleChildClick}
      selected={selectedChildren.includes(child)}
    />
  ))

  return (
    <div>
      {childComponents}
    </div>
  );
}
© www.soinside.com 2019 - 2024. All rights reserved.