React Native Ratings Component
react-native-ratings is a UI component library providing flexible star rating components for React Native applications. It supports both tap and swipe gestures for rating input, offering two main components: `Rating` for generic star ratings with various customization options (like custom images, types such as 'heart' or 'rocket'), and `AirbnbRating` which mimics Airbnb's rating style with review labels. The current stable version is 8.1.0, and the library maintains a fairly active release cadence, with frequent patch and minor updates addressing bugs and adding small features. A key differentiator is its out-of-the-box support for both tap and swipe interactions, custom iconography, and integrated TypeScript types since v8.0.1, making it a robust solution for user feedback collection.
Common errors
-
TypeError: Cannot read properties of undefined (reading 'call') at Rating.onFinishRating
cause The `onFinishRating` prop callback was not properly bound or is being called in a context where `this` is undefined (common in class components without binding or in functional components without correct state management).fixFor class components, ensure `this.onFinishRating = this.onFinishRating.bind(this);` in the constructor. For functional components, define the handler directly or use `useCallback`. -
Unable to resolve module './water.png' from '.../src/App.tsx'
cause The custom `ratingImage` source path for `type='custom'` is incorrect, or the image file does not exist at the specified location.fixVerify that the `require('./path/to/image.png')` path accurately points to your image asset. Check for typos or incorrect directory structures. -
Property 'Rating' does not exist on type 'typeof import("react-native-ratings")'.cause This TypeScript error often occurs when TypeScript cannot find the type definitions for `react-native-ratings` or when an older version without bundled types is used with a newer TypeScript configuration expecting types.fixEnsure `react-native-ratings` is version 8.0.1 or higher. If using an older version, install `@types/react-native-ratings` as a dev dependency (`npm install --save-dev @types/react-native-ratings`). Check your `tsconfig.json` for correct `typeRoots`. -
Invariant Violation: 'main' has not been registered. This can happen if:
cause While not directly from `react-native-ratings`, if the application fails to start and a `Rating` component is causing issues, it might be due to a React Native bundling problem, potentially related to asset handling or module resolution on older `react-native-ratings` versions.fixThis usually indicates a broader React Native setup issue. First, check that `react-native-ratings` is correctly installed. If on v8.0.2 or v8.0.3, upgrade to v8.0.4+. Clear Metro Bundler cache (`npm start -- --reset-cache`) or reinstall node_modules.
Warnings
- breaking Version 8.0.1 refactored components from class-based to functional and introduced official TypeScript support. Projects directly accessing internal class component instances, lifecycle methods, or relying on specific internal structures might experience breaking changes. Update your components to use functional patterns and hooks.
- gotcha Versions 8.0.2 and 8.0.3 contained a bug where assets (like default star images) were not properly included in the distributed build files. This could lead to ratings components appearing without their visual icons.
- gotcha When using `type='custom'`, the `ratingImage` prop expects a `require()` call for local assets (e.g., `require('./path/to/image.png')`). Providing just a string path or an incorrect import will result in images not being displayed.
- deprecated Prior to v8.0.1, official TypeScript types were not included with the package. Developers often relied on `@types/react-native-ratings` from the DefinitelyTyped repository. With v8.0.1+, types are bundled, making the external `@types` package redundant.
Install
-
npm install react-native-ratings -
yarn add react-native-ratings -
pnpm add react-native-ratings
Imports
- Rating
const Rating = require('react-native-ratings');import { Rating } from 'react-native-ratings'; - AirbnbRating
import AirbnbRating from 'react-native-ratings';
import { AirbnbRating } from 'react-native-ratings'; - RatingProps (type)
import { RatingProps } from 'react-native-ratings';import type { RatingProps } from 'react-native-ratings';
Quickstart
import React, { useState } from 'react';
import { View, Text, StyleSheet } from 'react-native';
import { Rating, AirbnbRating } from 'react-native-ratings';
const WATER_IMAGE = require('./water.png'); // Ensure 'water.png' is in your project assets
export default function App() {
const [tapRating, setTapRating] = useState(3);
const [airbnbRating, setAirbnbRating] = useState(5);
const [customRating, setCustomRating] = useState(7);
const handleTapRatingComplete = (rating: number) => {
console.log("Tap Rating set to: " + rating);
setTapRating(rating);
};
return (
<View style={styles.container}>
<Text style={styles.header}>Airbnb Rating Example</Text>
<AirbnbRating
count={11}
reviews={["Terrible", "Bad", "Meh", "OK", "Good", "Hmm...", "Very Good", "Wow", "Amazing", "Unbelievable", "Jesus"]}
defaultRating={airbnbRating}
size={20}
onFinishRating={(rating) => setAirbnbRating(rating)}
/>
<Text style={styles.header}>Star Rating Example</Text>
<Rating
showRating
onFinishRating={handleTapRatingComplete}
style={{ paddingVertical: 10 }}
startingValue={tapRating}
/>
<Text style={styles.header}>Heart Rating Example</Text>
<Rating
type='heart'
ratingCount={3}
imageSize={60}
showRating
onFinishRating={(rating) => console.log("Heart Rating: " + rating)}
/>
<Text style={styles.header}>Custom Image Rating</Text>
<Rating
type='custom'
ratingImage={WATER_IMAGE}
ratingColor='#3498db'
ratingBackgroundColor='#c8c7c8'
ratingCount={10}
imageSize={30}
onFinishRating={(rating) => setCustomRating(rating)}
style={{ paddingVertical: 10 }}
startingValue={customRating}
/>
</View>
);
}
const styles = StyleSheet.create({
container: {
flex: 1,
justifyContent: 'center',
alignItems: 'center',
backgroundColor: '#F5FCFF',
paddingTop: 50,
},
header: {
fontSize: 20,
marginTop: 20,
marginBottom: 10,
fontWeight: 'bold',
}
});