You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
## 📜 Description
Added ability to pass selector to `useKeyboardState` hook to query only
necessary updates.
## 💡 Motivation and Context
The concept of selectors should be very familiar to many RN developers,
since it's used in `redux` and `zustand` packages. I was also thinking
about optimizing the amount of re-renders for this hook, but initially
I've been thinking of using proxy (similar to what `react-hook-form` is
doing). But such approach will introduce a lot of complexity, so I
decided to keep the codebase simple and efficient, so added a concept of
selectors.
Additionally I re-worked documnetation mainly focusing on:
- adding a sample how `useKeyboardAnimation` can be used as alternative;
- making warnings/tips shorter with corresponding references;
- adding the usage for selectors concept;
- use a real-world example with `useKeyboardState` (conditional
rendering instead of changing styles).
## 📢 Changelog
<!-- High level overview of important changes -->
<!-- For example: fixed status bar manipulation; added new types
declarations; -->
<!-- If your changes don't affect one of platform/language below - then
remove this platform/language -->
### JS
- allow to pass selectors to `useKeyboardState`;
### Docs
- make warning/tips shorter with corresponding links;
- added `useKeyboardState` vs `useKeyboardAnimation` code reference;
- mention how to use selectors;
- re-work example app to match real-world scenarios usage.
## 🤔 How Has This Been Tested?
Tested manually in example project.
## 📸 Screenshots (if appropriate):
|Dark theme|Light theme|
|------------|------------|
|||
## 📝 Checklist
- [x] CI successfully passed
- [x] I added new mocks and corresponding unit-tests if library API was
changed
Copy file name to clipboardExpand all lines: docs/docs/api/hooks/keyboard/use-keyboard-state.mdx
+80-23Lines changed: 80 additions & 23 deletions
Original file line number
Diff line number
Diff line change
@@ -20,7 +20,42 @@ sidebar_position: 4
20
20
`useKeyboardState` is a hook which gives an access to current keyboard state. This hook combines data from `KeyboardController.state()` and `KeyboardController.isVisible()` methods and makes it reactive (i. e. triggers a re-render when keyboard state/visibility has changed).
21
21
22
22
:::warning
23
-
Use this hook only when you need to control `props` of views returned in JSX-markup. If you need to access the keyboard `state` in callbacks or event handlers then consider to use [KeyboardController.state()](../../keyboard-controller.md#state) or [KeyboardController.isVisible()](../../keyboard-controller.md#isvisible) methods instead. This allows you to retrieve values as needed without triggering unnecessary re-renders.
23
+
Don’t use `state` from `useKeyboardState` inside event handlers. It will cause unnecessary re-renders. See [common pitfalls](#-common-pitfalls) section for more details and alternatives.
24
+
:::
25
+
26
+
:::tip
27
+
Make sure that if you want to animate something based on keyboard presence then you've seen [optimize animation](#%EF%B8%8F-optimize-animations-with-native-threads) section.
28
+
:::
29
+
30
+
`useKeyboardState` allows you to pass a **selector** function to pick only the necessary part of the keyboard state data. This is a powerful technique to prevent unnecessary re-renders of your component when only a specific property of the keyboard state changes.
In this example, your component will only re-render when the `appearance` property of the `KeyboardState` changes, rather than for any change in the entire state object.
37
+
38
+
## Data structure
39
+
40
+
The `KeyboardState` is represented by following structure:
41
+
42
+
```ts
43
+
typeKeyboardState= {
44
+
isVisible:boolean;
45
+
height:number;
46
+
duration:number; // duration of the animation
47
+
timestamp:number; // timestamp of the event from native thread
48
+
target:number; // tag of the focused `TextInput`
49
+
type:string; // `keyboardType` property from focused `TextInput`
50
+
appearance:string; // `keyboardAppearance` property from focused `TextInput`
51
+
};
52
+
```
53
+
54
+
## 🚫 Common Pitfalls
55
+
56
+
### ⚠️ Avoid Unnecessary Re-renders
57
+
58
+
If you need to access the keyboard `state` in callbacks or event handlers then consider to use [KeyboardController.state()](../../keyboard-controller.md#state) or [KeyboardController.isVisible()](../../keyboard-controller.md#isvisible) methods instead. This allows you to retrieve values as needed without triggering unnecessary re-renders.
24
59
25
60
<divclassName="code-grid">
26
61
<divclassName="code-block">
@@ -30,7 +65,7 @@ Use this hook only when you need to control `props` of views returned in JSX-mar
Also make sure that if you need to change style based on keyboard presence then you are using corresponding [animated](./use-keyboard-animation) hooks to offload animation to a native thread and free up resources for JS thread.
68
-
:::
101
+
Don't use `useKeyboardState` for controlling styles, because:
69
102
70
-
## Data structure
103
+
- applying it directly to styles can lead to choppy animations;
104
+
- it changes its values frequently making excessive re-renders on each keyboard state change.
71
105
72
-
The `KeyboardState` is represented by following structure:
106
+
If you need to change styles then you can use "animated" hooks such as [useKeyboardAnimation](./use-keyboard-animation), [useReanimatedKeyboardAnimation](./use-reanimated-keyboard-animation) or even [useKeyboardHandler](./use-keyboard-handler) to offload animation to a native thread and free up resources for JS thread.
73
107
74
-
```ts
75
-
typeKeyboardState= {
76
-
isVisible:boolean;
77
-
height:number;
78
-
duration:number; // duration of the animation
79
-
timestamp:number; // timestamp of the event from native thread
80
-
target:number; // tag of the focused `TextInput`
81
-
type:string; // `keyboardType` property from focused `TextInput`
82
-
appearance:string; // `keyboardAppearance` property from focused `TextInput`
* React Hook that represents the current keyboard state on iOS and Android.
17
21
* It tracks keyboard visibility, height, appearance, type and other properties.
18
22
* This hook subscribes to keyboard events and updates the state reactively.
19
23
*
24
+
* @template T - A type of the returned object from the `selector`.
25
+
* @param selector - A function that receives the current keyboard state and picks only necessary properties to avoid frequent re-renders.
20
26
* @returns Object {@link KeyboardState|containing} keyboard state information.
21
27
* @see {@link https://kirillzyusko.github.io/react-native-keyboard-controller/docs/api/hooks/keyboard/use-keyboard-state|Documentation} page for more details.
0 commit comments