Skip to content

Instantly share code, notes, and snippets.

@r0b0t3d
Created July 10, 2021 09:06
Show Gist options
  • Save r0b0t3d/db629f5f4e249c7a5b6a3c211f2b8aa8 to your computer and use it in GitHub Desktop.
Save r0b0t3d/db629f5f4e249c7a5b6a3c211f2b8aa8 to your computer and use it in GitHub Desktop.
Use of useCallback and useMemo

1. Use

1.1. in callback

const handlePress = useCallback(() => {
	// handle press
}, [])

Good πŸ‘

<Button onPress={handlePress} />

Not good πŸ‘Ž

<Button onPress={() => handlePress()} />

1.2. use curry functions when possible

<FlatList
	renderItem={renderItem}
/>

Good πŸ‘

const handlePress = useCallback((item) => () => {
	// handle item press
}, [])

const renderItem = ({ item }) => {
	return <SomeComponent onPress={handlePress(item)} />
}

Not good πŸ‘Ž

const handlePress = useCallback((item) => {
	// handle item press
}, [])

const renderItem = ({ item }) => {
	return <SomeComponent onPress={() => handlePress(item)} />
}

2. No use

2.1. FlatList's render methods

<FlatList
	renderItem={renderItem}
	ListHeaderComponent={renderHeader}
/>

Good πŸ‘

const renderItem = ({ item }) => {
	return <SomeComponent onPress={handlePress(item)} />
}

const renderHeader = () => {
	return <SomeComponent />
}

Not good πŸ‘Ž

const renderItem = useCallback(({ item }) => {
	return <SomeComponent onPress={handlePress(item)} />
}, []);

const renderHeader = useCallback(() => {
	return <SomeComponent />
}, []);

2.2. Render item in array

const data = [];
return (
	<View>
		{data.map(renderItem)}
	<View>
)

Good πŸ‘

function renderItem() {
	return <SomeComponent />
}

Not good πŸ‘Ž

const renderItem = useCallback(() => {
	return <SomeComponent />
}, [])

1. Expensive calculations

function SomeComponent({ todos }) {
	const completedCount = ...
	
	return (
		<View>
			<Text>{`Completed: ${completedCount}`}</Text>
		</View>
	)
}

Good πŸ‘

const completedCount = useMemo(() => todos.reduce((acc, item) => {
		if (item.isCompleted) {
			return acc + 1,
		}
		return acc
	}, 0)
}, [todos])

Not good πŸ‘Ž

const completedCount = todos.reduce((acc, item) => {
	if (item.isCompleted) {
		return acc + 1,
	}
	return acc
}, 0)

2. Use as dependency in another hook

function SomeComponent({ todos }) {
	const completedItems = [...]

	const handleSubmit = useCallback(() => {
		// handle data submit
	}, [completedItems]);

	return (
		<View>
			{completedItems.map(renderItem)}
			<Pressable onPress={handleSubmit}>
				<Text>Submit</Text>
			</Pressable>
		</View>
	)
}

Good πŸ‘

const completedItems = useMemo(() => todos.filter(item => item.isCompleted), [todos]);

Not good πŸ‘Ž

const completedItems = todos.filter(item => item.isCompleted);
@ashisharora1692
Copy link

@GaylordP if I use currying as you said in 1.2 then component will rerender everytime because inner function will be recreated everytime and props will be changed.i tried few days ago before reading above

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment