From 1d7b7517e5faee4b85efb897d82ceb481aca2710 Mon Sep 17 00:00:00 2001 From: Rory Abraham <47436092+roryabraham@users.noreply.github.com> Date: Fri, 22 Apr 2022 06:07:23 -0700 Subject: [PATCH] feat: add imperative api to refresh state (#594) * feat: add imperative api to refresh state * docs: document refresh in README * Add example to example app * Update netinfo mock with refresh method --- README.md | 15 ++++++++++ example/ConnectionInfoRefresh.tsx | 46 +++++++++++++++++++++++++++++++ example/index.tsx | 9 ++++++ jest/netinfo-mock.js | 2 ++ src/index.ts | 13 +++++++++ src/internal/state.ts | 2 +- 6 files changed, 86 insertions(+), 1 deletion(-) create mode 100644 example/ConnectionInfoRefresh.tsx diff --git a/README.md b/README.md index 7f367030..0f54a6db 100644 --- a/README.md +++ b/README.md @@ -148,6 +148,7 @@ NetInfo.fetch().then(state => { * [`NetInfoCellularGeneration`](#netinfocellulargeneration) * **Methods:** * [`fetch()`](#fetch) + * [`refresh()`](#refresh) * [`addEventListener()`](#addeventlistener) * [`useNetInfo()`](#usenetinfo) @@ -345,6 +346,20 @@ NetInfo.fetch("wifi").then(state => { }); ``` +#### `refresh()` + +Updates NetInfo's internal state, then returns a `Promise` that resolves to a [`NetInfoState`](#netinfostate) object. This is similar to `fetch()`, but really only useful on platforms that do not supply internet reachability natively. For example, you can use it to immediately re-run an internet reachability test if a network request fails unexpectedly. + +**Example:** +```javascript +NetInfo.refresh().then(state => { + console.log("Connection type", state.type); + console.log("Is connected?", state.isConnected); +}); +``` + +This will also update subscribers using `addEventListener` and/or `useNetInfo`. + ## Troubleshooting ### Errors when building on Android diff --git a/example/ConnectionInfoRefresh.tsx b/example/ConnectionInfoRefresh.tsx new file mode 100644 index 00000000..245d3902 --- /dev/null +++ b/example/ConnectionInfoRefresh.tsx @@ -0,0 +1,46 @@ +/** + * Copyright (c) Facebook, Inc. and its affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + * + * @format + */ + +import * as React from 'react'; +import {Text, View, TouchableOpacity} from 'react-native'; +import NetInfo from '../src'; + +interface State { + connectionInfo: string; +} + +export default class ConnectionInfoCurrent extends React.Component< + Record, + State +> { + state = { + connectionInfo: 'Tap to refresh state', + }; + + componentDidMount(): void { + this._refreshState(); + } + + _refreshState = async (): Promise => { + const state = await NetInfo.refresh(); + this.setState({ + connectionInfo: JSON.stringify(state), + }); + }; + + render() { + return ( + + + {this.state.connectionInfo} + + + ); + } +} diff --git a/example/index.tsx b/example/index.tsx index 1cb7c37a..8c5b3c20 100644 --- a/example/index.tsx +++ b/example/index.tsx @@ -23,6 +23,7 @@ import { import ConnectionInfoSubscription from './ConnectionInfoSubscription'; import ConnectionInfoCurrent from './ConnectionInfoCurrent'; import ConnectionInfoFetch from './ConnectionInfoFetch'; +import ConnectionInfoRefresh from './ConnectionInfoRefresh'; import NetInfoHook from './NetInfoHook'; import IsConnected from './IsConnected'; @@ -51,6 +52,14 @@ const EXAMPLES: Example[] = [ return ; }, }, + { + id: 'refresh', + title: 'NetInfo.refresh', + description: 'Refresh the state on tap', + render() { + return ; + }, + }, { id: 'currentInfoSingle', title: 'Current Info Single', diff --git a/jest/netinfo-mock.js b/jest/netinfo-mock.js index dfceccf9..2c99e45d 100644 --- a/jest/netinfo-mock.js +++ b/jest/netinfo-mock.js @@ -16,11 +16,13 @@ const defaultState = { const RNCNetInfoMock = { configure: jest.fn(), fetch: jest.fn(), + refresh: jest.fn(), addEventListener: jest.fn(), useNetInfo: jest.fn(), }; RNCNetInfoMock.fetch.mockResolvedValue(defaultState); +RNCNetInfoMock.refresh.mockResolvedValue(defaultState); RNCNetInfoMock.useNetInfo.mockReturnValue(defaultState); RNCNetInfoMock.addEventListener.mockReturnValue(jest.fn()); diff --git a/src/index.ts b/src/index.ts index d0cd1f76..6e8a197d 100644 --- a/src/index.ts +++ b/src/index.ts @@ -64,6 +64,18 @@ export function fetch( return _state.latest(requestedInterface); } +/** + * Force-refreshes the internal state of the NetInfo library. + * + * @returns A Promise which contains the updated connection state. + */ +export function refresh(): Promise { + if (!_state) { + _state = createState(); + } + return _state._fetchCurrentState(); +} + /** * Subscribe to connection information. The callback is called with a parameter of type * [`NetInfoState`](README.md#netinfostate) whenever the connection state changes. Your listener @@ -119,6 +131,7 @@ export * from './internal/types'; export default { configure, fetch, + refresh, addEventListener, useNetInfo, }; diff --git a/src/internal/state.ts b/src/internal/state.ts index 6f8869db..bf1f4766 100644 --- a/src/internal/state.ts +++ b/src/internal/state.ts @@ -65,7 +65,7 @@ export default class State { this._subscriptions.forEach((handler): void => handler(nextState)); }; - private _fetchCurrentState = async ( + public _fetchCurrentState = async ( requestedInterface?: string, ): Promise => { const state = await NativeInterface.getCurrentState(requestedInterface);