├── .gitignore
├── README.md
├── docs
├── assets
│ └── react-icon.png
├── useAccessibilityInfo.md
├── useAppState.md
├── useBackHandler.md
├── useDimensions.md
├── useGeolocation.md
├── useKeyboard.md
└── useNetInfo.md
├── hooks
├── useAccessibilityInfo.js
├── useAppState.js
├── useBackHandler.js
├── useDimensions.js
├── useGeolocation.js
├── useKeyboard.js
└── useNetInfo.js
├── index.js
└── package.json
/.gitignore:
--------------------------------------------------------------------------------
1 | # node.js
2 | #
3 | node_modules/
4 | npm-debug.log
5 | yarn-error.log
6 | .DS_Store
7 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # react-native-use
2 |
3 |
4 |
5 | 🎣s for the React Native API
6 |
7 | This library is heavily inspired by [react-use](https://github.com/streamich/react-use) by [streamich](https://github.com/streamich).
8 |
9 | ## Installation
10 |
11 | ```bash
12 | yarn add react-native-use
13 | ```
14 |
15 | ```bash
16 | npm i react-native-use
17 | ```
18 |
19 | ------
20 |
21 | ## Description
22 |
23 | Currently, this library contains hook implementations for the React Native API; however, it seeks to become a repository of hook recipes useful to RN devs.
24 |
25 | ------
26 |
27 | ## Hooks
28 |
29 | ![rnlogo] [React Native API](https://facebook.github.io/react-native/)
30 |
31 | - [useAccessibilityInfo](./docs/useAccessibilityInfo.md)
32 | - [useAppState](./docs/useAppState.md)
33 | - [useBackHandler](./docs/useBackHandler.md)
34 | - [useDimensions](./docs/useDimensions.md)
35 | - [useGeolocation](./docs/useGeolocation.md)
36 | - [useKeyboard](./docs/useKeyboard.md)
37 | - [useNetInfo](./docs/useNetInfo.md)
38 |
39 | [rnlogo]: ./docs/assets/react-icon.png
40 |
41 |
--------------------------------------------------------------------------------
/docs/assets/react-icon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/alburdette619/react-native-use/10cbcc838878a08345181c8487d550ea0187f8d0/docs/assets/react-icon.png
--------------------------------------------------------------------------------
/docs/useAccessibilityInfo.md:
--------------------------------------------------------------------------------
1 | # useAccessibilityInfo
2 |
3 | React Native API 🎣 that adds an event listener for the `AccessibilityInfo` `change` event, and adds one for the `announcementFinished` on iOS. Also, this will return the initial state from `AccessibilityInfo.fetch()` as well as the other methods for use with the API.
4 |
5 | ## Usage
6 |
7 | ```javascript
8 | import {useAccessibilityInfo} from 'react-native-use'
9 |
10 | const [
11 | {readerEnabled, announcement, success},
12 | setAccessibilityFocus,
13 | announceForAccessibility
14 | ] = useAccessibilityInfo();
15 | ```
16 |
--------------------------------------------------------------------------------
/docs/useAppState.md:
--------------------------------------------------------------------------------
1 | # useAppState
2 |
3 | React Native API 🎣 that adds an event listener for the `AppState` `change` event . Also, this will return the initial state from `AccessibilityInfo.currentState`.
4 |
5 | ## Usage
6 |
7 | ```javascript
8 | import {useAppState} from 'react-native-use'
9 |
10 | const appState = useAppState();
11 | ```
12 |
--------------------------------------------------------------------------------
/docs/useBackHandler.md:
--------------------------------------------------------------------------------
1 | # useBackHandler
2 |
3 | React Native API 🎣 that adds an event listener for the `BackHandler` `hardwareBackPress` event given a callback to use.
4 |
5 | ## Usage
6 |
7 | ```javascript
8 | import {useBackHandler} from 'react-native-use'
9 |
10 | const handleBackPress = () => {
11 | this.goBack();
12 | return true;
13 | }
14 |
15 | useBackHandler(handleBackPress);
16 | ```
17 |
--------------------------------------------------------------------------------
/docs/useDimensions.md:
--------------------------------------------------------------------------------
1 | # useDimensions
2 |
3 | React Native API 🎣 that adds event listener(s) for the `Dimsnsions` `change` event. Also, this will return the initial Dimensions when called.
4 |
5 | ## Types
6 |
7 | ### DimensionsTypes
8 |
9 | React Native has two dimensions, `screen` and `window`. On iOS these are the same, but on Android the values returned are different. From [the docs](https://facebook.github.io/react-native/docs/0.59/dimensions#get):
10 |
11 | > For Android the `window` dimension will exclude the size used by the `status bar` (if not translucent) and `bottom navigation bar`
12 |
13 | Any number of types can be requested, but defaults are set per Platform.
14 |
15 | | Type | **Defaults** |
16 | | :----- | :----------- |
17 | | SCREEN | Android |
18 | | WINDOW | Android, iOS |
19 |
20 | ## Usage
21 |
22 | ```javascript
23 | import {useDimensions, types} from 'react-native-use'
24 |
25 | const {DimensionsTypes} = types;
26 | const {window: {height, width}} = useDimensions(DimensionsTypes.WINDOW);
27 | ```
28 |
--------------------------------------------------------------------------------
/docs/useGeolocation.md:
--------------------------------------------------------------------------------
1 | # useGeolocation
2 |
3 | React Native API 🎣 for the use of `navigator.geolocation`. It will return the initial state from `getCurrentPosition`. Watching can be setup as well.
4 |
5 | ## Usage
6 |
7 | ### Parameters
8 |
9 | Passed in as a single object with the following keys
10 |
11 | | Parameter Key | Required | Default Value |
12 | | ------------- | :------: | ------------- |
13 | | success | ☑ | - |
14 | | error | ☑ | - |
15 | | options | | {} |
16 | | shouldWatch | | False |
17 |
18 | ```javascript
19 | import {useGeolocation} from 'react-native-use'
20 |
21 | const success = location => console.log(location)
22 | const error = err => console.log(err)
23 |
24 | useGeolocation({success, error, options: {enableHighAccuracy: true}, shouldWatch: true});
25 | ```
26 |
--------------------------------------------------------------------------------
/docs/useKeyboard.md:
--------------------------------------------------------------------------------
1 | # useKeyboard
2 |
3 | React Native API 🎣 that adds event listener(s) for `Keyboard` events.
4 |
5 | ## Types
6 |
7 | ### KeyboardEventTypes
8 |
9 | React Native has six different event tyeps for the Keyboard API.
10 |
11 | Any number of types can be requested, by default, none are subscribed to. The following types can be used:
12 |
13 | - KEYBOARD_WILL_SHOW
14 | - KEYBOARD_DID_SHOW
15 | - KEYBOARD_WILL_HIDE
16 | - KEYBOARD_DID_HIDE
17 | - KEYBOARD_WILL_CHANGE_FRAME
18 | - KEYBOARD_DID_CHANGE_FRAME
19 |
20 | ## Usage
21 |
22 | ### Parameters
23 |
24 | Pass in a single object who's keys are `KeyboardEventTypes` and values are handlers for the specific keyboard events requested.
25 |
26 | ```javascript
27 | import {useKeyboard, types} from 'react-native-use'
28 |
29 | const {KeyboardEventTypes} = types;
30 |
31 | const handleKeyboardWillShow = () => console.log('Keyboard Will Show!')
32 |
33 | const keyboardState = useKeyboard({
34 | KeyboardEventTypes.KEYBOARD_WILL_SHOW: handleKeyboardWillShow
35 | });
36 | ```
37 |
38 |
--------------------------------------------------------------------------------
/docs/useNetInfo.md:
--------------------------------------------------------------------------------
1 | # useNetInfo
2 |
3 | React Native API 🎣 that adds an event listener to `NetInfo`. Also, this will return the initial state from `NetInfoInfo.fetch()`.
4 |
5 | ## Usage
6 |
7 | ```javascript
8 | import {useNetInfo} from 'react-native-use'
9 |
10 | const isConnected = useNetInfo();
11 | ```
12 |
13 |
--------------------------------------------------------------------------------
/hooks/useAccessibilityInfo.js:
--------------------------------------------------------------------------------
1 | import { useState, useEffect } from "react";
2 | import { AccessibilityInfo, Platform } from "react-native";
3 |
4 | const useAccessibilityInfo = () => {
5 | const [state, setState] = useState();
6 | const { setAccessibilityFocus, announceForAccessibility } = AccessibilityInfo;
7 |
8 | const handleStateChange = newState => setState({ ...state, ...newState });
9 | const getInitialState = async () =>
10 | handleStateChange({ readerEnabled: await AccessibilityInfo.fetch() });
11 |
12 | useEffect(() => {
13 | getInitialState();
14 | }, []);
15 |
16 | useEffect(() => {
17 | AccessibilityInfo.addEventListener("change", enabled =>
18 | handleStateChange({ readerEnabled: enabled })
19 | );
20 |
21 | if (Platform.OS === "ios") {
22 | AccessibilityInfo.addEventListener(
23 | "announcementFinished",
24 | handleStateChange
25 | );
26 | }
27 |
28 | return () => {
29 | AccessibilityInfo.removeEventListener("change", handleStateChange);
30 |
31 | if (Platform.OS === "ios") {
32 | AccessibilityInfo.removeEventListener(
33 | "announcementFinished",
34 | handleStateChange
35 | );
36 | }
37 | };
38 | });
39 |
40 | return [state, setAccessibilityFocus, announceForAccessibility];
41 | };
42 |
43 | export default useAccessibilityInfo;
44 |
--------------------------------------------------------------------------------
/hooks/useAppState.js:
--------------------------------------------------------------------------------
1 | import { useEffect, useState } from "react";
2 | import { AppState } from "react-native";
3 |
4 | const useAppState = () => {
5 | const [state, setState] = useState(AppState.currentState);
6 | const handleStateChange = state => setState(state);
7 |
8 | useEffect(() => {
9 | AppState.addEventListener("change", handleStateChange);
10 |
11 | return () => AppState.removeEventListener("change", handleStateChange);
12 | });
13 |
14 | return state;
15 | };
16 |
17 | export default useAppState;
18 |
--------------------------------------------------------------------------------
/hooks/useBackHandler.js:
--------------------------------------------------------------------------------
1 | import { useEffect } from "react";
2 | import { BackHandler } from "react-native";
3 |
4 | const useBackHandler = handleBackPress => {
5 | useEffect(() => {
6 | BackHandler.addEventListener("hardwareBackPress", handleBackPress);
7 |
8 | return () =>
9 | BackHandler.removeEventListener("hardwareBackPress", handleBackPress);
10 | });
11 |
12 | return BackHandler.exitApp;
13 | };
14 |
15 | export default useBackHandler;
16 |
--------------------------------------------------------------------------------
/hooks/useDimensions.js:
--------------------------------------------------------------------------------
1 | import { useEffect, useState } from "react";
2 | import { Dimensions, Platform } from "react-native";
3 |
4 | export const DimensionsTypes = {
5 | SCREEN: "screen",
6 | WINDOW: "window"
7 | };
8 |
9 | const defaultTypes = Platform.select({
10 | ios: [DimensionsTypes.WINDOW],
11 | android: Object.values(DimensionsTypes)
12 | });
13 |
14 | const useDimensions = (types = defaultTypes) => {
15 | const typesArray = Array.isArray(types) ? types : [types];
16 |
17 | const getDimensions = () =>
18 | typesArray.reduce((acc, type) => {
19 | return { ...acc, [type]: Dimensions.get(type) };
20 | }, {});
21 |
22 | const initialState = getDimensions();
23 | const [state, setState] = useState(initialState);
24 | const handleStateChange = () => setState(getDimensions());
25 |
26 | useEffect(() => {
27 | Dimensions.addEventListener("change", handleStateChange);
28 |
29 | return () => Dimensions.removeEventListener("change", handleStateChange);
30 | });
31 |
32 | return state;
33 | };
34 |
35 | export default useDimensions;
36 |
--------------------------------------------------------------------------------
/hooks/useGeolocation.js:
--------------------------------------------------------------------------------
1 | import { useEffect, useState, useCallback } from "react";
2 |
3 | const useGeolocation = ({
4 | success,
5 | error,
6 | options = {},
7 | shouldWatch = false
8 | }) => {
9 | const { geolocation } = navigator;
10 | const [state, setState] = useState({});
11 |
12 | const handleSuccess = useCallback(
13 | state => {
14 | setState(state);
15 | success(state);
16 | },
17 | [state]
18 | );
19 | const handleError = useCallback(
20 | state => {
21 | setState(state);
22 | error(state);
23 | },
24 | [state]
25 | );
26 |
27 | useEffect(() => {
28 | if (Object.keys(state).length === 0) {
29 | geolocation.getCurrentPosition(handleSuccess, handleError, options);
30 | }
31 | });
32 |
33 | let watchId;
34 | if (shouldWatch) {
35 | useEffect(() => {
36 | watchId = geolocation.watchPosition(handleSuccess, handleError, options);
37 |
38 | return () => {
39 | geolocation.clearWatch(watchId);
40 | watchId = null;
41 | };
42 | });
43 | } else if (watchId) {
44 | geolocation.clearWatch(watchId);
45 | watchId = null;
46 | }
47 | };
48 |
49 | export default useGeolocation;
50 |
--------------------------------------------------------------------------------
/hooks/useKeyboard.js:
--------------------------------------------------------------------------------
1 | import { useEffect } from "react";
2 | import { Keyboard } from "react-native";
3 |
4 | export const KeyboardEventTypes = {
5 | KEYBOARD_WILL_SHOW: "keyboardWillShow",
6 | KEYBOARD_DID_SHOW: "keyboardDidShow",
7 | KEYBOARD_WILL_HIDE: "keyboardWillHide",
8 | KEYBOARD_DID_HIDE: "keyboardDidHide",
9 | KEYBOARD_WILL_CHANGE_FRAME: "keyboardWillChangeFrame",
10 | KEYBOARD_DID_CHANGE_FRAME: "keyboardDidChangeFrame"
11 | };
12 |
13 | const useKeyboard = (handlers = []) => {
14 | const typesArray = Array.isArray(types) ? types : [types];
15 |
16 | const handleStateChange = (newState, type) =>
17 | handlers[type] && handlers[type](newState);
18 |
19 | useEffect(() => {
20 | typesArray.forEach(type =>
21 | Keyboard.addListener(type, newState => handleStateChange(newState, type))
22 | );
23 |
24 | return () => typesArray.forEach(type => Keyboard.removeAllListeners(type));
25 | });
26 | };
27 |
28 | export default useKeyboard;
29 |
--------------------------------------------------------------------------------
/hooks/useNetInfo.js:
--------------------------------------------------------------------------------
1 | import { useEffect, useState } from "react";
2 | import NetInfo from "@react-native-community/netinfo";
3 |
4 | const useNetInfo = () => {
5 | const [state, setState] = useState();
6 | const handleStateChange = state => setState(state);
7 | const getInitialState = async () => handleStateChange(await NetInfo.fetch());
8 |
9 | useEffect(() => {
10 | getInitialState();
11 | }, []);
12 |
13 | useEffect(() => {
14 | const unSub = NetInfo.addEventListener(handleStateChange);
15 |
16 | return () => unSub;
17 | });
18 |
19 | return state;
20 | };
21 |
22 | export default useNetInfo;
23 |
--------------------------------------------------------------------------------
/index.js:
--------------------------------------------------------------------------------
1 | import useAccessibilityInfo from "./hooks/useAccessibilityInfo";
2 | import useAppState from "./hooks/useAppState";
3 | import useBackHandler from "./hooks/useBackHandler";
4 | import useDimensions, { DimensionsTypes } from "./hooks/useDimensions";
5 | import useGeolocation from "./hooks/useGeolocation";
6 | import useKeyboard, { KeyboardEventTypes } from "./hooks/useKeyboard";
7 | import useNetInfo from "./hooks/useNetInfo";
8 |
9 | const types = {
10 | DimensionsTypes,
11 | KeyboardEventTypes
12 | };
13 |
14 | export {
15 | useAccessibilityInfo,
16 | useAppState,
17 | useBackHandler,
18 | useDimensions,
19 | useGeolocation,
20 | useKeyboard,
21 | useNetInfo,
22 | types
23 | };
24 |
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "react-native-use",
3 | "version": "1.1.0",
4 | "description": "Hooks for the React Native API",
5 | "main": "index.js",
6 | "scripts": {
7 | "test": "jest"
8 | },
9 | "repository": {
10 | "type": "git",
11 | "url": "git+https://github.com/alburdette619/react-native-use.git"
12 | },
13 | "keywords": [
14 | "react",
15 | "native",
16 | "react-native",
17 | "hooks"
18 | ],
19 | "author": "Adam Burdette",
20 | "license": "ISC",
21 | "bugs": {
22 | "url": "https://github.com/alburdette619/react-native-use/issues"
23 | },
24 | "homepage": "https://github.com/alburdette619/react-native-use#readme"
25 | }
26 |
--------------------------------------------------------------------------------