Skip to content

Commit

Permalink
Refactor code structure to make it easier for adding new examples (#3…
Browse files Browse the repository at this point in the history
…8799)

Summary:
Pull Request resolved: #38799

Refactor the performance comparison examples to make it easier to add new ones.

Changelog:
[General][Internal] - Code refactor

Reviewed By: rshest

Differential Revision: D47857126

fbshipit-source-id: fc8ffbcc94a23b896a53f599161f3bf6e9c2eaad
  • Loading branch information
Xin Chen authored and facebook-github-bot committed Aug 8, 2023
1 parent 93d9248 commit a8962ce
Show file tree
Hide file tree
Showing 7 changed files with 99 additions and 32 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,8 @@ import * as React from 'react';
import {StyleSheet, View, Text} from 'react-native';
import RNTesterPage from '../../components/RNTesterPage';
import RNTesterButton from '../../components/RNTesterButton';
import ReRenderWithObjectPropExample from './ReRenderWithObjectPropExample';
import ReRenderWithNonPureChildExample from './ReRenderWithNonPureChildExample';
import * as performanceComparisonExamples from './performanceComparisonExamples';
import type {RNTesterModuleExample} from '../../types/RNTesterTypes';

const {useState, useCallback, useMemo} = React;
const SHOW_NOTHING = 'SHOW_NOTHING';
Expand Down Expand Up @@ -114,29 +114,21 @@ exports.title = 'Performance Comparison Examples';
exports.category = 'Basic';
exports.description =
'Compare performance with bad and good examples. Use React DevTools to highlight re-renders is recommended.';
exports.examples = [
{
title: ReRenderWithNonPureChildExample.title,
description: ReRenderWithNonPureChildExample.description,
render: function (): React.Node {
return (
<PerfExampleWrapper
badExample={<ReRenderWithNonPureChildExample.Bad />}
goodExample={<ReRenderWithNonPureChildExample.Good />}
/>
);
},
},
{
title: ReRenderWithObjectPropExample.title,
description: ReRenderWithObjectPropExample.description,
render: function (): React.Node {
return (
<PerfExampleWrapper
badExample={<ReRenderWithObjectPropExample.Bad />}
goodExample={<ReRenderWithObjectPropExample.Good />}
/>
);
},
},
];

const examples: Array<RNTesterModuleExample> = Object.keys(
performanceComparisonExamples,
).map(name => {
const example = performanceComparisonExamples[name];
return {
title: example.title,
description: example.description,
render: () => (
<PerfExampleWrapper
badExample={<example.Bad />}
goodExample={<example.Good />}
/>
),
};
});

exports.examples = examples;
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,8 @@

import * as React from 'react';
import {Text} from 'react-native';
import ItemList from './ItemList';
import {LIST_100_ITEMS} from './itemData';
import ItemList from '../components/ItemList';
import {LIST_100_ITEMS} from '../components/itemData';
import type {ScrollEvent} from 'react-native/Libraries/Types/CoreEventTypes';

const {useCallback, useState} = React;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,8 @@

import * as React from 'react';
import {Text} from 'react-native';
import ItemList from './ItemList';
import {LIST_100_ITEMS} from './itemData';
import ItemList from '../components/ItemList';
import {LIST_100_ITEMS} from '../components/itemData';
import type {ScrollEvent} from 'react-native/Libraries/Types/CoreEventTypes';

const {useState, useCallback} = React;
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
/**
* 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
* @oncall react_native
*/

'use strict';

import type {ItemDataType} from '../components/itemData';

import * as React from 'react';
import ItemList from '../components/ItemList';
import {LIST_1000_ITEMS} from '../components/itemData';

const {useState, useEffect} = React;
const ItemListMemo = React.memo(ItemList);

function BadExample(props: {listData: ItemDataType[], filteredText: string}) {
const {listData, filteredText} = props;
const [visibleListData, setVisibleListData] =
useState<ItemDataType[]>(listData);

useEffect(() => {
setVisibleListData(
listData.filter(item =>
item.name.toUpperCase().includes(filteredText.toUpperCase()),
),
);
}, [listData, filteredText]);

return <ItemListMemo data={visibleListData} />;
}

function GoodExample(props: {listData: ItemDataType[], filteredText: string}) {
const {listData, filteredText} = props;
const visibleListData = listData.filter(item =>
item.name.toUpperCase().includes(filteredText.toUpperCase()),
);

return <ItemListMemo data={visibleListData} />;
}

function SetStateInWrongEffectBadExample(): React.Node {
return <BadExample listData={LIST_1000_ITEMS} filteredText="f8" />;
}

function SetStateInWrongEffectGoodExample(): React.Node {
return <GoodExample listData={LIST_1000_ITEMS} filteredText="f8" />;
}

export default {
title: 'Re-render with unnecessary effect and state changes',
description:
'You may not need an effect in your component. State updates in unnecessary effects will trigger re-render that can be avoided.',
Bad: SetStateInWrongEffectBadExample,
Good: SetStateInWrongEffectGoodExample,
};
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
/**
* 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
* @oncall react_native
*/

export {default as ReRenderWithNonPureChildExample} from './ReRenderWithNonPureChildExample';
export {default as ReRenderWithObjectPropExample} from './ReRenderWithObjectPropExample';

0 comments on commit a8962ce

Please sign in to comment.