React Native中被包裹的组件为何每次都会重渲染?
问题:React Native中颜色选择器重渲染行为差异的原因
在React Native(Expo)的Stack Navigator页面函数式组件中,引入了react-native-wheel-color-picker颜色选择器组件,搭配一个用于更新状态的按钮。发现两个不同的渲染行为:
- 直接渲染
<ColorPicker />时,点击按钮更新test状态,颜色选择器不会触发重渲染 - 把颜色选择器包裹在简单函数式组件
ColorPickerFn中后,每次点击按钮更新状态,这个包裹后的组件都会触发重渲染
示例代码:
import { useState } from 'react'; import ColorPicker from 'react-native-wheel-color-picker' const [test, setTest] = useState<number>(0); const ColorPickerFn = () => { // 这个组件每次状态更新都会重渲染,为什么? return (<ColorPicker />) } return ( <> <ColorPickerFn /> <ColorPicker /> <Button onPress={ () => { setTest(test + 1); }}>{test}</Button> </> );
原因分析
直接渲染
<ColorPicker />的情况:
当父组件状态test更新时,父组件会重新执行并生成新的React元素树。React的协调(Reconciliation)机制会对比新旧元素树,发现<ColorPicker />的组件类型(ColorPicker)和props(此处无传入props)与之前完全一致,因此会复用已有的组件实例,不会触发重渲染——这是React默认的性能优化行为。包裹在
ColorPickerFn中渲染的情况:ColorPickerFn是定义在父组件内部的函数,父组件每次重渲染时,这个函数都会被重新创建一次,相当于每次都是一个全新的组件类型(React通过引用判断组件类型)。React对比新旧元素树时,会认为<ColorPickerFn />是一个完全不同的组件,于是卸载旧的ColorPickerFn实例,重新挂载新的实例,内部的<ColorPicker />自然也会跟着重新渲染。
内容的提问来源于stack exchange,提问作者Stumblor
相关产品推荐
相关产品推荐

