Skip to content
This repository was archived by the owner on Dec 29, 2022. It is now read-only.

Commit 2da7295

Browse files
committed
docs: updated usage & performance guide
1 parent e538cbb commit 2da7295

4 files changed

Lines changed: 94 additions & 34 deletions

File tree

README.md

Lines changed: 36 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -43,10 +43,6 @@ Convert hooks into shared states between react components
4343
- [Dark Mode][expo-app] with React Native on expo. Project in [`example/`](https://github.com/react-native-toolkit/rex-state/tree/master/example) directory
4444
-[Why Rex State?](#why-rex-state)
4545

46-
## Motivation
47-
48-
Rex State was initially built as a state management library. But after using it in many projects, its main purpose became creating hooks where the data returned by the hook can be shared across multiple react components.
49-
5046
## Requirements
5147

5248
Rex State is built purely on React Hooks hence it requires React > 16.8 to work.
@@ -63,35 +59,51 @@ npm i rex-state
6359

6460
## Usage
6561

66-
```jsx
67-
import { createRexStore } from 'rex-state';
62+
Consider the following hook which lets you toggle theme between light & dark modes
6863

69-
// A simple hook to toggle theme modes between 'light' & 'dark'
70-
const useThemeHook = (initialTheme = 'light') => {
64+
```jsx
65+
const useThemeMode = (initialTheme = 'light') => {
7166
const [theme, setTheme] = useState(initialTheme);
7267

7368
const toggleTheme = () => setTheme(theme === 'light' ? 'dark' : 'light');
7469

7570
return [theme, toggleTheme];
7671
};
72+
```
73+
74+
You can use the `createRexStore` module from rex state to create a provider & a store hook to access the result of your `useThemeMode`
75+
76+
```jsx
77+
import { createRexStore } from 'rex-state';
7778

78-
// using `createRexStore` to create a Provider & a Hook with shared state
7979
const { useStore: useTheme, RexProvider: ThemeProvider } = createRexStore(
80-
useThemeHook
80+
useThemeMode
8181
);
82+
```
83+
84+
The `useStore` hook & `RexProvider` are renamed to `useTheme` & `ThemeProvider` for use in the application.
85+
86+
Now you can wrap your entire Application inside the `ThemeProvider` to ensure the context is setup properly for the `useTheme` hook.
8287

83-
// Use the `ThemeProvider` at the top level of your React component tree
88+
```jsx
8489
const App = () => {
85-
// `initialTheme` value can be supplied using the value prop of `ThemeProvider`
8690
return (
8791
<ThemeProvider value="dark">
8892
{/* Rest of your application */}
8993
<ToggleButton />
94+
<ThemeText />
9095
</ThemeProvider>
9196
);
9297
};
98+
```
99+
100+
> Note: The value of the argument of `useThemeMode` function - `initialTheme` is supplied to the `ThemeProvider` using the `value` prop. The `value` prop only supports a single argument. Hence if your hook requires multiple arguments, you can pass them as a single object
93101
94-
// All components can now access the `useTheme` hook
102+
Once you add the `ThemeProvider` to the top of your application's tree, the child components can now use the `useTheme` hook to access the result of your `useThemeMode` hook. This time, when you call `toggleTheme` in any of the child components, it will cause your entire application tree to re-render & all the components that use the `useTheme` hook will have the updated value!
103+
104+
The following is a toggle button that toggles the theme when users click on it.
105+
106+
```jsx
95107
const ToggleButton = () => {
96108
const [theme, toggleTheme] = useTheme();
97109

@@ -102,9 +114,11 @@ const ToggleButton = () => {
102114
</View>
103115
);
104116
};
117+
```
118+
119+
The next component is a text block that simply displays the theme's mode
105120
106-
// Calling `toggleTheme` in above component will cause updates
107-
// in all the components in the Application tree using the context API
121+
```jsx
108122
const ThemeText = () => {
109123
const [theme] = useTheme();
110124

@@ -117,11 +131,15 @@ const ThemeText = () => {
117131
};
118132
```
119133
134+
Invoking the `toggleTheme` function from the `<ToggleButton/>` component updates the `<ThemeText/>` component. This means your hook is now a shared state between the two components!
135+
136+
Also, check out the [counter example](https://codesandbox.io/s/rex-counter-2m4zy?file=/src/App.js) from codesandbox
137+
138+
Rex State is good for some use cases and not suitable for some use cases since it uses the [React Context](https://reactjs.org/docs/context.html#api) API which is considered inefficient as a change causes the entire React child tree to re-render. Read the [performance](https://rex-state.netlify.app/?path=/story/intro-performance--page) section to see how to use Rex State effectively.
139+
120140
## Why Rex State?
121141
122-
- It's Tiny!
123-
- Simple & un-opinionated
124-
- Makes hooks much more powerful
142+
Rex State is a handy utility to make your hooks more powerful. It is simple, un-opinionated & is very tiny!
125143
126144
## Licenses
127145

example/src/stories/API.stories.mdx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,10 +5,10 @@ import { Meta } from '@storybook/addon-docs/blocks';
55
## `createRexStore`
66

77
```tsx
8-
createRexStore: <T, V>(useRexState: (value?: V) => T) => {
8+
createRexStore: <T, V>(useRexState: (value?: V) => T) => ({
99
RexProvider: (props: { children: ReactNode; value?: V }) => JSX.Element;
1010
useStore: () => T;
11-
};
11+
});
1212
```
1313

1414
`createRexStore` accepts your hook as the argument and returns an object with two properties ﹣

example/src/stories/GettingStarted.stories.mdx

Lines changed: 44 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -36,35 +36,53 @@ Convert hooks into shared states between react components
3636

3737
Rex State allows you to convert the result of your hooks into a shared state between multiple react components using the Context API.
3838

39-
```jsx
40-
import { createRexStore } from 'rex-state';
39+
## Usage
4140

42-
// A simple hook to toggle theme modes between 'light' & 'dark'
43-
const useThemeHook = (initialTheme = 'light') => {
41+
Consider the following hook which lets you toggle theme between light & dark modes
42+
43+
```jsx
44+
const useThemeMode = (initialTheme = 'light') => {
4445
const [theme, setTheme] = useState(initialTheme);
4546

4647
const toggleTheme = () => setTheme(theme === 'light' ? 'dark' : 'light');
4748

4849
return [theme, toggleTheme];
4950
};
51+
```
52+
53+
You can use the `createRexStore` module from rex state to create a provider & a store hook to access the result of your `useThemeMode`
54+
55+
```jsx
56+
import { createRexStore } from 'rex-state';
5057

51-
// using `createRexStore` to create a Provider & a Hook with shared state
5258
const { useStore: useTheme, RexProvider: ThemeProvider } = createRexStore(
53-
useThemeHook
59+
useThemeMode
5460
);
61+
```
62+
63+
The `useStore` hook & `RexProvider` are renamed to `useTheme` & `ThemeProvider` for use in the application.
64+
65+
Now you can wrap your entire Application inside the `ThemeProvider` to ensure the context is setup properly for the `useTheme` hook.
5566

56-
// Use the `ThemeProvider` at the top level of your React component tree
67+
```jsx
5768
const App = () => {
58-
// `initialTheme` value can be supplied using the value prop of `ThemeProvider`
5969
return (
6070
<ThemeProvider value="dark">
6171
{/* Rest of your application */}
6272
<ToggleButton />
73+
<ThemeText />
6374
</ThemeProvider>
6475
);
6576
};
77+
```
78+
79+
> Note: The value of the argument of `useThemeMode` function - `initialTheme` is supplied to the `ThemeProvider` using the `value` prop. The `value` prop only supports a single argument. Hence if your hook requires multiple arguments, you can pass them as a single object
6680
67-
// All components can now access the `useTheme` hook
81+
Once you add the `ThemeProvider` to the top of your application's tree, the child components can now use the `useTheme` hook to access the result of your `useThemeMode` hook. This time, when you call `toggleTheme` in any of the child components, it will cause your entire application tree to re-render & all the components that use the `useTheme` hook will have the updated value!
82+
83+
The following is a toggle button that toggles the theme when users click on it.
84+
85+
```jsx
6886
const ToggleButton = () => {
6987
const [theme, toggleTheme] = useTheme();
7088

@@ -75,9 +93,11 @@ const ToggleButton = () => {
7593
</View>
7694
);
7795
};
96+
```
7897
79-
// Calling `toggleTheme` in above component will cause updates
80-
// in all the components in the Application tree using the context API
98+
The next component is a text block that simply displays the theme's mode
99+
100+
```jsx
81101
const ThemeText = () => {
82102
const [theme] = useTheme();
83103

@@ -90,13 +110,25 @@ const ThemeText = () => {
90110
};
91111
```
92112
93-
## Working Example
113+
## In Action
114+
115+
<br />
94116
95117
<DarkModeProvider value="dark">
96118
<ToggleButton />
97119
<ThemeText />
98120
</DarkModeProvider>
99121
122+
<br />
123+
<br />
124+
<br />
125+
126+
As you can see, calling the `toggleTheme` function from the `<ToggleButton/>` component updates the `<ThemeText/>` component. This means your hook is now a shared state between the two components!
127+
128+
Also, check out the [counter example](https://codesandbox.io/s/rex-counter-2m4zy?file=/src/App.js) from codesandbox
129+
130+
Rex State is good for some use cases and not suitable for some use cases since it uses the [React Context](https://reactjs.org/docs/context.html#api) API which is considered inefficient as a change causes the entire React child tree to re-render. Read the performance section to see how to use Rex State effectively.
131+
100132
[coffee-badge]: https://img.shields.io/badge/-%E2%98%95%EF%B8%8F%20buy%20me%20a%20coffee-e85b46
101133
[coffee-url]: https://www.buymeacoffee.com/daniakash
102134
[sponsor-badge]: https://img.shields.io/badge/-%F0%9F%8F%85%20sponsor%20this%20project-e85b46

example/src/stories/Performance.stories.mdx

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,16 @@ import { Meta } from '@storybook/addon-docs/blocks';
66

77
Rex State makes the values returned by Hooks shareable using the React Context API. But there are knows performance limitations since changing the value of Context causes the entire Application tree to re-render.
88

9-
Rex State used to have an [`InjectStore`](https://github.com/daniakash/rex-state/tree/9809c7a7a6f71c1644a7d94a058b5606cf49da11#performance) HOC which implemented the solutions suggested by [Dan Abramov](https://github.com/facebook/react/issues/15156#issuecomment-474590693). This HOC is removed in v1.0 as the goal of Rex State is no longer to be a state management tool, but, to be an utility to share hooks across components.
9+
## When not to use Rex State
1010

11-
You can directly implement the performance optimizations suggested in the above comment if you need. If you are looking for a powerful state management tool that can efficiently avoid unnecessary re-renders, you can try [recoil](https://recoiljs.org/) or [zustand](https://github.com/react-spring/zustand).
11+
Rex State is not a state management library. It is a utility to quickly share a hook between two components. Hence if you are working with data that changes often and is shared by a large number of components, it is a good idea to avoid rex state.
12+
13+
Rex State used to have an [`InjectStore`](https://github.com/daniakash/rex-state/tree/9809c7a7a6f71c1644a7d94a058b5606cf49da11#performance) HOC which implemented the solutions suggested by [Dan Abramov](https://github.com/facebook/react/issues/15156#issuecomment-474590693). This HOC is removed in v1.0 as the goal of Rex State is no longer to be a state management tool. You can directly implement the performance optimizations suggested in [the comment](https://github.com/facebook/react/issues/15156#issuecomment-474590693) if you need.
14+
15+
If you are looking for a powerful state management tool that can efficiently avoid unnecessary re-renders, you can try [recoil](https://recoiljs.org/) or [zustand](https://github.com/react-spring/zustand).
16+
17+
## When you can use Rex State
18+
19+
Rex State is good for data that doesn't change often. For example, managing color schemes of dark mode & light mode throughout your application is a good use case. As the theme modes do not change often. Also, changing the mode usually requires all the components to re-render.
20+
21+
If you have data that changes often but you want to share the data of your hook with a limited number of components alone, then instead of wrapping your entire application inside the `RexProvider`, you can only wrap the nearest common parent of the required components inside the `RexProvider`. This ensures the re-renders are limited only to that parent and the rest of your application is not disturbed.

0 commit comments

Comments
 (0)