使用react-card-flip时如何避免特定卡片翻回时子组件重渲染
核心原因是卡片翻转时父组件的翻转状态更新,连带传给子组件的props引用发生变化,触发了不必要的子组件重渲染,可通过以下方案解决:
方案1:为子组件添加渲染缓存
- 函数组件使用
React.memo包裹,默认对props做浅比较,仅当props实际变化时才触发重渲染。如果包含复杂类型props(对象、函数),可传入第二个参数自定义比较逻辑:
// 子组件定义示例 const BackComponent = React.memo(({ cardData, onFlip }) => { return ( <div> This is the back of the card. <button onClick={onFlip}>Click to flip</button> </div> ) // 自定义比较规则:仅当业务数据或操作方法变化时才重渲染 }, (prevProps, nextProps) => { return prevProps.cardData === nextProps.cardData && prevProps.onFlip === nextProps.onFlip })
- 类组件可继承
React.PureComponent,或重写shouldComponentUpdate方法过滤不需要触发重渲染的props变动。
方案2:缓存父组件传递的引用类型props
如果父组件传递给子组件的函数、对象是在渲染时动态生成的,会导致每次渲染引用都不一致,即使内容没有变化也会触发子组件重渲染,需提前缓存:
- 类组件在构造函数中绑定事件方法,避免render中动态生成方法:
class CardContainer extends React.Component { constructor(props) { super(props) this.state = { isFlipped: false } // 构造函数内绑定,保证引用不变 this.handleFlip = this.handleFlip.bind(this) } handleFlip() { this.setState(prev => ({ isFlipped: !prev.isFlipped })) } render() { return ( <ReactCardFlip isFlipped={this.state.isFlipped}> <YOUR_FRONT_COMPONENT>This is the front of the card.Click to flip</YOUR_FRONT_COMPONENT> <YOUR_BACK_COMPONENT onFlip={this.handleFlip}> This is the back of the card. <button onClick={this.handleFlip}>Click to flip</button> </YOUR_BACK_COMPONENT> </ReactCardFlip> ) } }
- 函数组件使用
useCallback缓存事件方法、useMemo缓存对象类型props:
function CardContainer() { const [isFlipped, setIsFlipped] = useState(false) // 用useCallback缓存翻转方法,依赖为空保证引用不变 const handleFlip = useCallback(() => { setIsFlipped(prev => !prev) }, []) return ( <ReactCardFlip isFlipped={isFlipped}> <YOUR_FRONT_COMPONENT>This is the front of the card.Click to flip</YOUR_FRONT_COMPONENT> <YOUR_BACK_COMPONENT onFlip={handleFlip}> This is the back of the card. <button onClick={handleFlip}>Click to flip</button> </YOUR_BACK_COMPONENT> </ReactCardFlip> ) }
方案3:剥离子组件不需要的props
不要将父组件的isFlipped翻转状态等子组件用不到的参数传给子组件,避免无关状态变动触发子组件更新。
内容的提问来源于stack exchange,提问作者Alex Zhang
相关产品推荐
相关产品推荐

