HWEvent
TVEventHandler and its respective hook useTVEventHandler are listeners for TV remote events. The UserInputManager class fires a JS event which are handled by the callback respectively for implementation of custom handling to these events.
HWEvent: Data emitted from the native event emitter.
eventType:
up - This event is received when the UP DPaD control is triggered.
down - This event is received when the DOWN DPaD control is triggered.
right - This event is received when the RIGHT DPaD control is triggered.
left - This event is received when the LEFT DPaD control is triggered.
select - This event is received when the RETURN DPaD control is triggered.
menu - This event is received when the MENU DPaD control is triggered.
back - This event is received when the BACK DPaD control is triggered.
playpause - This event is received when the PLAY/PAUSE DPaD control is triggered.
rewind - This event is received when the REWIND DPaD control is triggered.
forward - This event is received when the FORWARD DPaD control is triggered.
eventAction:
0 : The respective key is in the pressed/KEY_DOWN state.
1 : The respective key is in the released/KEY_UP state.
deviceIdentifier: object
The device identifier: the device id of which produces this key event.
it contains the following fields:
uniqueId?: string, for example: 90:39:5F:2C:0C:06 (Bluetooth Address)
busId?: number, for example: 0x0005 bluetooth
vendorId?: number, for exmaple: 0x0171
productId?: number, for example: 0x042f
version?: number, for example: 0x0060
When input device uniq is empty, or the app has no privilege "com.amazon.input.device.id.access"
the deviceIdentifier is undefined.
@see https://reactnative.dev/docs/building-for-tv
export type HWEvent = {
eventType: 'up' | 'down' | 'right' | 'left' | 'select' | 'menu' | 'back' | 'playpause' | 'skip_backward'
| 'skip_forward' | 'page_up' | 'page_down' | 'page_left' | 'page_right' | 'info' | 'more' | string;
eventKeyAction?: -1 | 1 | 0 | number;
deviceIdentifier?: {
uniqueId?: string;
busId?: number;
vendorId?: number;
productId?: number;
version?: number;
};
};
## Example
```HWEvent Example
{% comment %}
import React, {useRef, useState} from 'react';
{% endcomment %}
{% comment %}
import {
{% endcomment %}
ColorValue,
HWEvent,
StyleSheet,
Text,
TouchableOpacity,
View,
useTVEventHandler,
} from 'react-native';
const backgroundColors = ['#283593', '#1A237E', '#0D47A1', '#1565C0'];
export const App = () => {
const [backgroundColor, setBackgroundColor] = useState<ColorValue>(
backgroundColors[0],
);
const [buttonText, setButtonText] = useState<string>('myTVEventHandler');
const colorIdx = useRef<number>(0);
const styles = getStyles(backgroundColor);
const myTVEventHandler = (event: HWEvent) => {
setButtonText(JSON.stringify(event));
};
useTVEventHandler(myTVEventHandler);
1,1 Top
const handleButtonPress = () => {
// wrapping index through array above
const nextColor = (colorIdx.current + 1) % backgroundColors.length;
setBackgroundColor(backgroundColors[nextColor]);
colorIdx.current = nextColor;
};
const hexColor = JSON.stringify(backgroundColor).replace(/"/g, '');
return (
<View style={styles.container}>
<TouchableOpacity
style={styles.button}
onPress={handleButtonPress}
testID="sampleButton">
<Text style={styles.buttonLabel}>{buttonText}</Text>
</TouchableOpacity>
<Text style={styles.colorLabel}>{hexColor}</Text>
</View>
);
};
const getStyles = (bgColor: ColorValue) =>
StyleSheet.create({
container: {
flex: 1,
flexDirection: 'column',
backgroundColor: bgColor,
justifyContent: 'center',
alignItems: 'center',
},
button: {
alignItems: 'center',
backgroundColor: '#303030',
borderColor: 'navy',
borderRadius: 10,
borderWidth: 1,
paddingVertical: 12,
paddingHorizontal: 32,
},
buttonLabel: {
color: 'white',
fontSize: 22,
fontFamily: 'Amazon Ember',
},
colorLabel: {
color: 'white',
position: 'absolute',
top: 32,
right: 32,
fontSize: 32,
},
});
Reference
Props
eventType
| Type | | —————————— | | string |
eventAction
| Type | | —————————— | | 0,1 |
deviceIdentifier Vega + TV Only
| Type |
|---|
| { |
| uniqueId?: string; |
| busId?: number; |
| vendorId?: number; |
| productId?: number; |
| version?: number; |
| }; |
Last updated: May 13, 2026

