From 2d0fabf9accf2a3baa673e06e53eca345b62d52a Mon Sep 17 00:00:00 2001 From: streamich Date: Tue, 20 Aug 2019 20:17:55 +0200 Subject: [PATCH] =?UTF-8?q?feat:=20=F0=9F=8E=B8=20use=20only=20one=20useSt?= =?UTF-8?q?ate=20and=20one=20useEffect=20call?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/useBattery.ts | 87 ++++++++++++++++++----------------------------- 1 file changed, 34 insertions(+), 53 deletions(-) diff --git a/src/useBattery.ts b/src/useBattery.ts index c2f6834f..3f675665 100644 --- a/src/useBattery.ts +++ b/src/useBattery.ts @@ -2,6 +2,8 @@ import * as React from 'react'; import * as isEqual from 'react-fast-compare'; import { off, on } from './util'; +const { useState, useEffect } = React; + export interface BatteryState { charging: boolean; chargingTime: number; @@ -33,68 +35,47 @@ function useBatteryMock(): UseBatteryState { } function useBattery(): UseBatteryState { - const [state, setState] = React.useState({ isSupported: true, fetched: false }); - const battery = React.useRef(); - const isMounted = React.useRef(false); + const [state, setState] = useState({ isSupported: true, fetched: false }); - const handleChange = React.useCallback(() => { - if (!isMounted.current || !battery.current) { - return; - } + useEffect(() => { + let isMounted = true; + let battery: BatteryManager | null = null; - const newState: UseBatteryState = { - isSupported: true, - fetched: true, - level: battery.current.level, - charging: battery.current.charging, - dischargingTime: battery.current.dischargingTime, - chargingTime: battery.current.chargingTime, + const handleChange = () => { + if (!isMounted || !battery) { + return; + } + const newState: UseBatteryState = { + isSupported: true, + fetched: true, + level: battery.level, + charging: battery.charging, + dischargingTime: battery.dischargingTime, + chargingTime: battery.chargingTime, + }; + !isEqual(state, newState) && setState(newState); }; - !isEqual(state, newState) && setState(newState); - }, [state, setState]); - - const bindBatteryEvents = React.useCallback(() => { - if (!battery.current || !isMounted.current) { - return; - } - - on(battery.current, 'chargingchange', handleChange); - on(battery.current, 'chargingtimechange', handleChange); - on(battery.current, 'dischargingtimechange', handleChange); - on(battery.current, 'levelchange', handleChange); - }, [handleChange]); - const unbindBatteryEvents = React.useCallback(() => { - if (!battery.current) { - return; - } - - off(battery.current, 'chargingchange', handleChange); - off(battery.current, 'chargingtimechange', handleChange); - off(battery.current, 'dischargingtimechange', handleChange); - off(battery.current, 'levelchange', handleChange); - }, [handleChange]); - - React.useEffect(() => { - bindBatteryEvents(); - handleChange(); // this one is for case when update performed between unbind and bind, extremely rare, but better to handle - - return unbindBatteryEvents; - }, [handleChange]); - - React.useEffect(() => { - isMounted.current = true; - (navigator as NavigatorWithPossibleBattery).getBattery!().then((bat: BatteryManager) => { - battery.current = bat; - - bindBatteryEvents(); + if (!isMounted) { + return; + } + battery = bat; + on(battery, 'chargingchange', handleChange); + on(battery, 'chargingtimechange', handleChange); + on(battery, 'dischargingtimechange', handleChange); + on(battery, 'levelchange', handleChange); handleChange(); }); return () => { - isMounted.current = false; - unbindBatteryEvents(); + isMounted = false; + if (battery) { + off(battery, 'chargingchange', handleChange); + off(battery, 'chargingtimechange', handleChange); + off(battery, 'dischargingtimechange', handleChange); + off(battery, 'levelchange', handleChange); + } }; }, []);