useBattery
React hook to track the battery status of a user's device.
Add the hook via the CLI:
npx @novajslabs/cli add useBattery
npx @novajslabs/cli add useBattery
pnpm dlx @novajslabs/cli add useBattery
Or copy and paste the code into your project:
import { useState, useEffect } from "react";
interface BatteryManager {
level: number;
charging: boolean;
chargingTime: number;
dischargingTime: number;
addEventListener(
type: string,
listener: EventListener | EventListenerObject | null,
options?: boolean | AddEventListenerOptions
): void;
removeEventListener(
type: string,
listener: EventListener | EventListenerObject | null,
options?: boolean | EventListenerOptions
): void;
}
interface BatteryState {
supported: boolean;
loading: boolean;
level: number | null;
charging: boolean | null;
chargingTime: number | null;
dischargingTime: number | null;
}
interface NavigatorWithBattery extends Navigator {
getBattery: () => Promise<BatteryManager>;
}
export const useBattery = () => {
const [batteryState, setBatteryState] = useState<BatteryState>({
supported: true,
loading: true,
level: null,
charging: null,
chargingTime: null,
dischargingTime: null,
});
useEffect(() => {
const _navigator = navigator as NavigatorWithBattery;
let battery: BatteryManager;
const handleBatteryChange = () => {
setBatteryState({
supported: true,
loading: false,
level: battery.level,
charging: battery.charging,
chargingTime: battery.chargingTime,
dischargingTime: battery.dischargingTime,
});
};
if (!_navigator.getBattery) {
setBatteryState((batteryState) => ({
...batteryState,
supported: false,
loading: false,
}));
return;
}
_navigator.getBattery().then((_battery) => {
battery = _battery;
handleBatteryChange();
_battery.addEventListener("levelchange", handleBatteryChange);
_battery.addEventListener("chargingchange", handleBatteryChange);
_battery.addEventListener("chargingtimechange", handleBatteryChange);
_battery.addEventListener("dischargingtimechange", handleBatteryChange);
});
return () => {
if (battery) {
battery.removeEventListener("levelchange", handleBatteryChange);
battery.removeEventListener("chargingchange", handleBatteryChange);
battery.removeEventListener("chargingtimechange", handleBatteryChange);
battery.removeEventListener(
"dischargingtimechange",
handleBatteryChange
);
}
};
}, []);
return batteryState;
};
import { useState, useEffect } from "react";
export const useBattery = () => {
const [batteryState, setBatteryState] = useState({
supported: true,
loading: true,
level: null,
charging: null,
chargingTime: null,
dischargingTime: null,
});
useEffect(() => {
let battery;
const handleBatteryChange = () => {
setBatteryState({
supported: true,
loading: false,
level: battery.level,
charging: battery.charging,
chargingTime: battery.chargingTime,
dischargingTime: battery.dischargingTime,
});
};
if (!navigator.getBattery) {
setBatteryState((batteryState) => ({
...batteryState,
supported: false,
loading: false,
}));
return;
}
navigator.getBattery().then((_battery) => {
battery = _battery;
handleBatteryChange();
_battery.addEventListener("levelchange", handleBatteryChange);
_battery.addEventListener("chargingchange", handleBatteryChange);
_battery.addEventListener("chargingtimechange", handleBatteryChange);
_battery.addEventListener("dischargingtimechange", handleBatteryChange);
});
return () => {
if (battery) {
battery.removeEventListener("levelchange", handleBatteryChange);
battery.removeEventListener("chargingchange", handleBatteryChange);
battery.removeEventListener("chargingtimechange", handleBatteryChange);
battery.removeEventListener(
"dischargingtimechange",
handleBatteryChange
);
}
};
}, []);
return batteryState;
};
Requirements
React 16.8 or higher
Return values
supported
Type: boolean
Represents whether the Battery Status API is supported in the browser (true
) or not (false
).
loading
Type: boolean
Represents if the battery information is loading (true
) or not (false
).
level
Type: number | null
Represents the level of the battery. 0.0
means that the battery is discharged, and 1.0
means the battery is fully charged.
charging
Type: boolean | null
Represents whether the battery is charging (true
) or not (false
).
chargingTime
Type: number | null
Represents the time remaining in seconds until the battery is completely charged.
dischargingTime
Type: number | null
Represents the time remaining in seconds until the battery is completely discharged.
Example
import { useBattery } from "./hooks/useBattery";
const App = () => {
const { level, charging } = useBattery();
return (
<div>
<p>Battery level:{level && level * 100}</p>
<p>{charging ? "Battery charging" : "Battery not charging"}</p>
</div>
);
};
export default App;
Use cases
Here are some use cases where this React hook is useful:
- Displaying the battery level in a user interface
- Low battery level notifications