-
-
Save gourav-singhal/d4d331d2320f7f9127f27227e7f2762f to your computer and use it in GitHub Desktop.
Revisions
-
mrousavy revised this gist
Apr 16, 2021 . 1 changed file with 1 addition and 1 deletion.There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -86,7 +86,7 @@ return <View style={style} /> * Reanimated styles from `useAnimatedStyle`, as those have to be dynamic. > See [react-native-style-utilities](https://github.com/mrousavy/react-native-style-utilities) for the `useStyle` hook <br /><br /><br /><br /><br /><br /> -
mrousavy revised this gist
Apr 9, 2021 . 1 changed file with 2 additions and 0 deletions.There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -274,9 +274,11 @@ If your app feels slow, try the [react-native-performance](https://github.com/ob <a align="right" href="https://twitter.com/mrousavy"> <img src="https://img.shields.io/twitter/follow/mrousavy?label=Follow%20%40mrousavy&style=social" /> </a> <br /> <a align="right" href="https://github.com/mrousavy?tab=followers"> <img src="https://img.shields.io/github/followers/mrousavy?label=Follow%20%40mrousavy&style=social" /> </a> <br /> <a align="right" href='https://ko-fi.com/F1F8CLXG' target='_blank'> <img height='36' style='border:0px;height:36px;' src='https://az743702.vo.msecnd.net/cdn/kofi2.png?v=0' border='0' alt='Buy Me a Coffee at ko-fi.com' /> </a> -
mrousavy revised this gist
Apr 9, 2021 . 1 changed file with 4 additions and 6 deletions.There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -271,15 +271,13 @@ If your app feels slow, try the [react-native-performance](https://github.com/ob <div align="right"> <a align="right" href="https://twitter.com/mrousavy"> <img src="https://img.shields.io/twitter/follow/mrousavy?label=Follow%20%40mrousavy&style=social" /> </a> <a align="right" href="https://github.com/mrousavy?tab=followers"> <img src="https://img.shields.io/github/followers/mrousavy?label=Follow%20%40mrousavy&style=social" /> </a> <a align="right" href='https://ko-fi.com/F1F8CLXG' target='_blank'> <img height='36' style='border:0px;height:36px;' src='https://az743702.vo.msecnd.net/cdn/kofi2.png?v=0' border='0' alt='Buy Me a Coffee at ko-fi.com' /> </a> </div> -
mrousavy revised this gist
Apr 9, 2021 . 1 changed file with 16 additions and 1 deletion.There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -267,4 +267,19 @@ If your app feels slow, try the [react-native-performance](https://github.com/ob <br /><br /><br /><br /><br /><br /> <p align="center"><b>memoize!!</b></p> <br /><br /><br /><br /><br /><br /> <div align="right"> <a align="right" href='https://ko-fi.com/F1F8CLXG' target='_blank'> <img height='36' style='border:0px;height:36px;' src='https://az743702.vo.msecnd.net/cdn/kofi2.png?v=0' border='0' alt='Buy Me a Coffee at ko-fi.com' /> </a> <br/> <a align="right" href="https://github.com/mrousavy?tab=followers"> <img src="https://img.shields.io/github/followers/mrousavy?label=Follow%20%40mrousavy&style=social" /> </a> <br/> <a align="right" href="https://twitter.com/mrousavy"> <img src="https://img.shields.io/twitter/follow/mrousavy?label=Follow%20%40mrousavy&style=social" /> </a> </div> -
mrousavy revised this gist
Mar 30, 2021 . 1 changed file with 2 additions and 1 deletion.There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -52,7 +52,8 @@ Reference comparisons simply compare the memory address of the variable, so only If you create objects in your render function, they will be re-created on every single render. This means when you create an object in the first render, it is not _reference-equal_ to the object in the second render. For this very reason, memoization exists. * Use the `useMemo` hook to memoize arrays and objects which will keep their reference equality (and won't get re-created on each render) as long as the dependencies (second argument) stay the same. Also use `useMemo` to cache heavy computations, such as array operations, filtering, etc. * Use the `useCallback` hook to memoize a function. In general, function components can be optimized more easily due to the concept of [hooks](https://reactjs.org/docs/hooks-overview.html). You can however apply similar techniques for class components, just be aware that this will result in a lot more code. -
mrousavy revised this gist
Mar 30, 2021 . 1 changed file with 1 addition and 1 deletion.There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -18,7 +18,7 @@ It's important to memoize heavy computations as well as arrays and object creati A [Pure Component](https://reactjs.org/docs/react-api.html#reactpurecomponent) (or a `React.memo` component) does not re-render if it's props are _shallow equal_. Each variable you create in your render function will get re-allocated on each render. While this is not a problem for **value types**, this causes **reference types** to be different on every render. When you pass those variables down to **pure components** via props, they will still re-render even though the props are logically the same. Often those variables even go over the Bridge and make your app slow. ## Reference equality -
mrousavy revised this gist
Mar 30, 2021 . 1 changed file with 11 additions and 5 deletions.There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -12,17 +12,21 @@ inputs occur again. &nbs # Memoization in React It's important to memoize heavy computations as well as arrays and object creations so that they don't get re-created on every render. A re-render occurs when state changes, redux dispatches some action, or when the user types into a text input (re-render for every single key press). You don't want to run a lot of operations in those renders for very obvious reasons - so no heavy filtering, no list operations, etc. ## Pure Components A [Pure Component](https://reactjs.org/docs/react-api.html#reactpurecomponent) (or a `React.memo` component) does not re-render if it's props are _shallow equal_. Each variable you create in your render function will get re-allocated on each render. While this is not a problem for value types, this causes reference types to be different on every render. When you pass those variables down to pure components via props, they will still re-render even though the props are logically the same. Often those variables even go over the Bridge and make your app slow. ## Reference equality When a pure component re-renders, it compares the previous props to the current props and checks if they are _shallow-equal_. ### Value types **Numbers**, **strings** and **booleans** are **value types**, which means they can be _compared by value_: ```js const i1 = 7; @@ -32,7 +36,7 @@ const equal = i1 === i2; // true ### Reference types **Objects**, **arrays** and **functions** are **reference types**, which means they cannot be compared by their logical value, but have to be _compared by reference_: ```js const o1 = { x: 7 }; @@ -56,6 +60,8 @@ In general, function components can be optimized more easily due to the concept While animations and performance intensive tasks are scheduled on native threads, your entire business logic runs on a single JavaScript thread, so make sure you're doing as little work as possible there. Doing too much work on the JavaScript thread can be compared to a high ping in a video game - you can still look around smoothly, but you can't really play the game because every interaction takes too long. Native components (`<View>`, `<Text>`, `<Image>`, `<Blurhash>`, ...) have to pass props to native via the bridge. They can be memoized, so React compares the props for _shallow-equality_ and only passes them over the bridge if they are different than the props from the last render. If you don't memoize correctly, you might up passing props over the bridge for every single render, causing the bridge to be very occupied. See the [Styles](#styles) example - styles will get sent over the bridge on every re-render! Here are a few examples to help you avoid doing too much work on your JavaScript thread: # Examples -
mrousavy revised this gist
Mar 30, 2021 . 1 changed file with 13 additions and 7 deletions.There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -18,29 +18,35 @@ Each variable you create in your render function will get re-allocated each rend ## Reference equality When a React component re-renders, it compares the previous props to the current props and checks if they are _shallow-equal_. ### Value types Numbers, strings and booleans are **value types**, which means they can be _compared by value_: ```js const i1 = 7; const i2 = 7; const equal = i1 === i2; // true ``` ### Reference types Objects, arrays and functions are **reference types**, which means they cannot be compared by their logical value, but have to be _compared by reference_: ```js const o1 = { x: 7 }; const o2 = { x: 7 }; const equal = o1 === o2; // false ``` Reference comparisons simply compare the memory address of the variable, so only `o1 === o1` would be `true` in the above code example. > There are libraries like [deep-equal](https://github.com/inspect-js/node-deep-equal) to compare objects by actual equality, but that's not _shallow equality_ anymore. ### React If you create objects in your render function, they will be re-created on every single render. This means when you create an object in the first render, it is not _reference-equal_ to the object in the second render. For this very reason, memoization exists. Use the `useMemo` hook to memoize arrays and objects which will keep their reference equality (and won't get re-created on each render) as long as the dependencies (second argument) stay the same. Use the `useCallback` hook to memoize a function. -
mrousavy revised this gist
Mar 30, 2021 . 1 changed file with 1 addition and 1 deletion.There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -14,7 +14,7 @@ inputs occur again. &nbs It's important to memoize heavy computations as well as arrays and object creations so that they don't get re-created on every render. A re-render occurs when state changes, redux dispatches some action, or when the user types into a text input (re-render for every single key press). You don't want to run a lot of operations in those renders for very obvious reasons. So no heavy filtering, no list operations, etc. Each variable you create in your render function will get re-allocated each render. While this is not a problem for types that can be _compared by value_ (numbers, booleans, strings), this causes objects which have to be _compared by reference_ (objects, arrays, functions) to be different on every render. When those objects don't maintain reference equality, React thinks that you passed a different variable to subcomponents, and will trigger re-renders for those too. Often those variables even go over the Bridge and make your app slow. ## Reference equality -
mrousavy revised this gist
Mar 30, 2021 . 1 changed file with 1 addition and 1 deletion.There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -246,7 +246,7 @@ If your component renders the same result given the same props, you can wrap it ## react-native-performance If your app feels slow, try the [react-native-performance](https://github.com/oblador/react-native-performance) library and it's flipper plugin to profile your app's performance in various aspects such as _time to interactive_, _component render time_, _script execution_ and more. <br /><br /><br /><br /><br /><br /> -
mrousavy revised this gist
Mar 30, 2021 . 1 changed file with 6 additions and 0 deletions.There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -244,6 +244,12 @@ If your component renders the same result given the same props, you can wrap it <br /><br /><br /><br /><br /><br /> ## react-native-performance If your app feels slow, try the [react-native-performance](https://github.com/oblador/react-native-performance) library and it's flipper plugin to profile your app's performance. <br /><br /><br /><br /><br /><br /> # Conclusion <br /><br /><br /><br /><br /><br /> -
mrousavy revised this gist
Mar 30, 2021 . 1 changed file with 26 additions and 1 deletion.There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -153,7 +153,9 @@ function MyComponent(props) { ```jsx function MyComponent(props) { const scrollViewProps = useMemo(() => ({ horizontal: props.isHorizontal }), [props.isHorizontal]); return <RecyclerListView scrollViewProps={scrollViewProps} />; } ``` @@ -216,6 +218,29 @@ function ComponentImWorkingOn() { You can also use the [why-did-you-render](https://github.com/welldone-software/why-did-you-render) library to find out _why_ a component has re-rendered (prop changes, state changes, ...) and possibly catch mistakes early on. <br /><br /><br /><br /><br /><br /> ## `React.memo` ### Bad ```jsx export const MyComponent = (props) => { return ... } ``` ### Good ```jsx const MyComponentImpl = (props) => { return ... } export const MyComponent = React.memo(MyComponentImpl); ``` If your component renders the same result given the same props, you can wrap it in a call to `React.memo(...)` for a performance boost in some cases by memoizing the result. This means that React will skip rendering the component, and reuse the last rendered result. See [the official docs for `React.memo`](https://reactjs.org/docs/react-api.html#reactmemo), and [use `React.memo(...)` wisely](https://dmitripavlutin.com/use-react-memo-wisely/). <br /><br /><br /><br /><br /><br /> -
mrousavy revised this gist
Mar 30, 2021 . 1 changed file with 8 additions and 4 deletions.There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -144,14 +144,18 @@ function MyComponent(props) { ### Bad ```jsx function MyComponent(props) { return <RecyclerListView scrollViewProps={{ horizontal: props.isHorizontal }} />; } ``` ### Good ```jsx function MyComponent(props) { const scrollViewProps = useMemo(() => ({ horizontal: props.isHorizontal }), [props.isHorizontal]); return <RecyclerListView scrollViewProps={scrollViewProps} />; } ``` <br /><br /><br /><br /><br /><br /> @@ -176,7 +180,7 @@ function MyComponent() { } ``` This applies to objects as well as functions which don't depend on the component's state or props. Always use this if you can, since it's even more efficient than `useMemo` and `useCallback`. <br /><br /><br /><br /><br /><br /> -
mrousavy revised this gist
Mar 30, 2021 . 1 changed file with 7 additions and 3 deletions.There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -119,18 +119,22 @@ Make sure to also think about other calls in the renderer, e.g. `useSelector`, ` <br /><br /><br /><br /><br /><br /> ## Forward-propagating Functions ### Bad ```jsx function MyComponent(props) { return <PressableOpacity onPress={() => props.logoutUser()} /> } ``` ### Good ```jsx function MyComponent(props) { return <PressableOpacity onPress={props.logoutUser} /> } ``` <br /><br /><br /><br /><br /><br /> -
mrousavy revised this gist
Mar 26, 2021 . 1 changed file with 1 addition and 1 deletion.There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -196,7 +196,7 @@ const [me, setMe] = useState(() => users.find((u) => u.id === myUserId)); ## Count re-renders When writing new components I always put a log statement in my render function to passively watch how often my component re-renders while I'm working on it. In general, components should re-render as little as possible, and if I see a lot of logs appearing in my console I know I did something wrong. It's a good practice to put this function in your component once you start working on it, and remove it once done. ```jsx function ComponentImWorkingOn() { -
mrousavy revised this gist
Mar 26, 2021 . 1 changed file with 2 additions and 2 deletions.There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -48,9 +48,9 @@ In general, function components can be optimized more easily due to the concept ### React Native While animations and performance intensive tasks are scheduled on native threads, your entire business logic runs on a single JavaScript thread, so make sure you're doing as little work as possible there. Doing too much work on the JavaScript thread can be compared to a high ping in a video game - you can still look around smoothly, but you can't really play the game because every interaction takes too long. Here are a few examples to help you avoid doing too much work on your JavaScript thread: # Examples -
mrousavy revised this gist
Mar 26, 2021 . 1 changed file with 3 additions and 1 deletion.There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -40,7 +40,9 @@ In this case, two objects get created. Since objects can get quite complex and g ### React In React your component's `render()` function (or simply a function component's function) is executed on each render. If you create objects in this function, they will be re-created on every single render. This means when you create an object in the first render, it is not reference-equal to the second render. For this very reason, memoization exists. Use the `useMemo` hook to memoize arrays and objects which will keep their reference equality (and won't get re-created on each render) as long as the dependencies (second argument) stay the same. Use the `useCallback` hook to memoize a function. In general, function components can be optimized more easily due to the concept of [hooks](https://reactjs.org/docs/hooks-overview.html). You can however apply similar techniques for class components, just be aware that this will result in a lot more code. -
mrousavy revised this gist
Mar 26, 2021 . 1 changed file with 2 additions and 0 deletions.There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -71,6 +71,8 @@ return <View style={style} /> * Reanimated styles from `useAnimatedStyle`, as those have to be dynamic. > See [useStyle.ts](https://gist.github.com/mrousavy/bc3b748c56330bec09f128ecb4be0acb) <br /><br /><br /><br /><br /><br /> ## Arrays -
mrousavy created this gist
Mar 26, 2021 .There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -0,0 +1,214 @@ <div align="center"> <blockquote> In computing, memoization or memoisation <br/> is an optimization technique used primarily <br/> to speed up computer programs by storing <br/> the results of expensive function calls and <br/> returning the cached result when the same <br/> inputs occur again. <br/> — <a href="https://en.wikipedia.org/wiki/Memoization"><i>wikipedia</i></a> </blockquote> </div> # Memoization in React It's important to memoize heavy computations as well as arrays and object creations so that they don't get re-created on every render. A re-render occurs when state changes, redux dispatches some action, or when the user types into a text input (re-render for every single key press). You don't want to run a lot of operations in those renders for very obvious reasons. So no heavy filtering, no list operations, etc. If variables get re-created each render, they won't maintain reference equality. When they don't maintain reference equality, React thinks that you passed a different variable to subcomponents, and will trigger re-renders for those too. Often those variables even go over the Bridge and make your app slow. ## Reference equality When a React component re-renders, it compares the previous props to the current props and checks if they are _shallow-equal_. Assuming you create two variables, both of the same type and same value, they are not guaranteed to be equal. Only "value types" can be shallow-compared successfully, while "reference types" have to be _reference equal_. Here's a code example to demonstrate this: ```js const i1 = 7; const i2 = 7; const equal = i1 === i2; ``` In this case, numbers are "value types" and can be compared by value. They are equal, the variable `equal` is therefore `true`. **This applies to numbers, booleans and strings**. ```js const o1 = { x: 7 }; const o2 = { x: 7 }; const equal = o1 === o2; ``` In this case, two objects get created. Since objects can get quite complex and go deeper than a single value, they are only compared for _reference equality_. In this case, we have two objects, and `o1` is a reference to the first object, while `o2` is a reference to the second object. This means, they are not _reference-equal_, `equals` is therefore `false`. **This applies to objects, arrays and functions**. ### React In React your component's `render()` function (or simply a function component's function) is executed on each render. If you create objects in this function, they will be re-created on every single render. This means when you create an object in the first render, it is not reference-equal to the second render. For this very reason, memoization exists. Use the `useMemo` hook to memoize arrays and objects, which will keep their reference equality (and won't get re-created on each render) as long as the dependencies (second argument) don't change. Use the `useCallback` hook to memoize a function. In general, function components can be optimized more easily due to the concept of [hooks](https://reactjs.org/docs/hooks-overview.html). You can however apply similar techniques for class components, just be aware that this will result in a lot more code. ### React Native While animations and performance intensive tasks are scheduled on native threads, your entire business logic runs on a single JavaScript thread, so make sure you're doing as little work as possible there. Overloading the JavaScript thread can be compared to a high ping in a video game - you can still look around smoothly, but you can't really play the game because every interaction takes too long. Here are a few examples to help you avoid overloading your JavaScript thread: # Examples ## Styles ### Bad ```jsx return <View style={[styles.container, { backgroundColor: 'red' }]} /> ``` ### Good ```jsx const style = useStyle(() => [styles.container, { backgroundColor: 'red' }], []); return <View style={style} /> ``` ### Exceptions * Reanimated styles from `useAnimatedStyle`, as those have to be dynamic. <br /><br /><br /><br /><br /><br /> ## Arrays Using `filter`, `map` or other array operations in renderers will run the entire operation again for every render. ### Bad ```jsx return <Text>{users.filter((u) => u.status === "online").length} users online</Text> ``` ### Good ```jsx const onlineCount = useMemo(() => users.filter((u) => u.status === "online").length, [users]); return <Text>{onlineCount} users online</Text> ``` You can also apply this to render multiple React views with `.map`. Those can be memoized with `useMemo` too. <br /><br /><br /><br /><br /><br /> ## Functions ### Bad ```jsx return <View onLayout={(layout) => console.log(layout)} /> ``` ### Good ```jsx const onLayout = useCallback((layout) => { console.log(layout); }, []); return <View onLayout={onLayout} /> ``` Make sure to also think about other calls in the renderer, e.g. `useSelector`, `useComponentDidAppear` - wrap the callback there too! <br /><br /><br /><br /><br /><br /> ## Dumb Functions ### Bad ```jsx return <PressableOpacity onPress={() => logoutUser()} /> ``` ### Good ```jsx return <PressableOpacity onPress={logoutUser} /> ``` <br /><br /><br /><br /><br /><br /> ## Objects ### Bad ```jsx return <RecyclerListView scrollViewProps={{ horizontal: true }} />; ``` ### Good ```jsx const scrollViewProps = useMemo(() => ({ horizontal: true }), []); return <RecyclerListView scrollViewProps={scrollViewProps} />; ``` <br /><br /><br /><br /><br /><br /> ## Lift out of render ### Bad ```jsx function MyComponent() { return <RecyclerListView scrollViewProps={{ horizontal: true }} />; } ``` ### Good ```jsx const SCROLL_VIEW_PROPS = { horizontal: true } function MyComponent() { return <RecyclerListView scrollViewProps={SCROLL_VIEW_PROPS} />; } ``` This applies to objects as well as functions which don't depend on the component's state or props. Always use this, since it's even more efficient than `useMemo` and `useCallback`. <br /><br /><br /><br /><br /><br /> ## Initial States ### Bad ```jsx const [me, setMe] = useState(users.find((u) => u.id === myUserId)); ``` ### Good ```jsx const [me, setMe] = useState(() => users.find((u) => u.id === myUserId)); ``` [The `useState` hook accepts an initializer function](https://reactjs.org/docs/hooks-reference.html#lazy-initial-state). While the first example ("Bad") runs the `.find` on every render, the second example only runs the passed function once to initialize the state. <br /><br /><br /><br /><br /><br /> ## Count re-renders When writing new components I always put a log statement in my render function to passively watch how often my component re-renders. In general, components should re-render as little as possible, and if I see a lot of logs appearing in my console I know I did something wrong. It's a good practice to put this function in your component while you're working on it, and remove it once done. ```jsx function ComponentImWorkingOn() { // code console.log('re-rendering ComponentImWorkingOn!'); return <View />; } ``` You can also use the [why-did-you-render](https://github.com/welldone-software/why-did-you-render) library to find out _why_ a component has re-rendered (prop changes, state changes, ...) and possibly catch mistakes early on. <br /><br /><br /><br /><br /><br /> # Conclusion <br /><br /><br /><br /><br /><br /> <p align="center"><b>memoize!!</b></p> <br /><br /><br /><br /><br /><br />