Skip to content

Commit 41c257a

Browse files
feat: created v0.0.4-beta
1 parent b0a2914 commit 41c257a

6 files changed

Lines changed: 290 additions & 114 deletions

File tree

.npmignore

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
node_modules
2+
3+
src
4+
.husky
5+
.editorconfig
6+
.eslintrc.js
7+
.gitignore
8+
.lintstagedrc.json
9+
.nvmrc
10+
.prettierignore
11+
.prettierrc.json
12+
commitlint.config.js
13+
rollup.config.js
14+
tsconfig.json
15+
yarn.lock

README.md

Lines changed: 239 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,241 @@
11
# react-easy-context-api
22

3-
This package has the objective of abstracting the creation of contexts in react and is in beta phase, with its documentation under construction.
3+
[![npm](https://img.shields.io/npm/v/react-easy-context-api)](https://www.npmjs.com/package/react-easy-context-api)
4+
[![size](https://img.shields.io/bundlephobia/minzip/react-easy-context-api)](https://bundlephobia.com/result?p=react-easy-context-api)
5+
6+
## Introduction
7+
8+
Many times when using the React Context API we create unnecessary repetitive and extensive code.
9+
10+
And, React Context and useContext is often used to avoid prop drilling,
11+
however it's known that there's a performance issue.
12+
When a context value is changed, all components that useContext
13+
will re-render.
14+
15+
To solve this issue,
16+
[useContextSelector](https://github.com/reactjs/rfcs/pull/119)
17+
is proposed and later proposed
18+
[Speculative Mode](https://github.com/reactjs/rfcs/pull/150)
19+
with context selector support.
20+
This library provides an easy way to build and use the Context API with these issues fixed.
21+
22+
This package is constructed above the [use-context-selector](https://github.com/dai-shi/use-context-selector).
23+
24+
## Install
25+
26+
This package requires some peer dependencies, which you need to install by yourself.
27+
28+
```bash
29+
yarn add react-easy-context-api react scheduler
30+
```
31+
32+
Notes for library authors:
33+
34+
Please do not forget to keep `"peerDependencies"` and
35+
note instructions to let users to install peer dependencies.
36+
37+
## Technical memo
38+
39+
To make it work like original React context, it uses
40+
[useReducer cheat mode](https://overreacted.io/a-complete-guide-to-useeffect/#why-usereducer-is-the-cheat-mode-of-hooks) intentionally.
41+
It also requires `useContextUpdate` to behave better in Concurrent Mode.
42+
(You don't need to use it in Legacy Mode.)
43+
44+
## Usage
45+
46+
```tsx
47+
// cats-context.tsx
48+
import { useState } from 'react'
49+
50+
import { createContext } from 'react-easy-context-api'
51+
52+
type MyContext = {
53+
pettedCats: number
54+
currentCats: number
55+
}
56+
57+
const { useSelector, Provider } = createContext<MyContext>({
58+
pettedCats: 0
59+
currentCats: 0
60+
})
61+
62+
const CatsProvider = ({ children }) => {
63+
const [pettedCats, setPettedCats] = useState(0)
64+
const [currentCats, setCurrentCats] = useState(0)
65+
66+
// ... your context logic :)
67+
68+
return (
69+
<Provider value={{
70+
pettedCats,
71+
currentCats
72+
}}>
73+
{children}
74+
</Provider>
75+
)
76+
}
77+
78+
export {
79+
CatsProvider,
80+
useSelector
81+
}
82+
83+
// ... in your components
84+
const CatsPetted = () => {
85+
const catsPettedNumber = useSelector(state => state.pettedCats)
86+
87+
return (
88+
<p>Petted cats: {catsPettedNumber}</p>
89+
)
90+
}
91+
92+
const CurrentCats = () => {
93+
const currentCatsNumber = useSelector(state => state.currentCats)
94+
95+
return (
96+
<p>Current cats: {currentCatsNumber}</p>
97+
)
98+
}
99+
100+
const App = () => (
101+
<CatsProvider>
102+
<CatsPetted />
103+
<CurrentCats />
104+
</CatsProvider>
105+
)
106+
```
107+
108+
## API
109+
110+
### createContext
111+
112+
This creates a special context.
113+
114+
#### Parameters
115+
116+
- `defaultValue` **Value**
117+
118+
#### Examples
119+
120+
```ts
121+
import { createContext } from 'react-easy-context-api'
122+
123+
type PersonContext = {
124+
firstName: string
125+
familyName: string
126+
}
127+
128+
const PersonContext = createContext<PersonContext>({ firstName: '', familyName: '' })
129+
```
130+
131+
### Returns:
132+
133+
#### useSelector
134+
135+
This hook returns context selected value by selector.
136+
137+
It will trigger re-render if only the selected value is referentially changed.
138+
139+
The selector should return referentially equal result for same input for better performance.
140+
141+
##### Parameters
142+
143+
- `selector` **function (value: Value): Selected**
144+
145+
##### Examples
146+
147+
```tsx
148+
const MyComponent = () => {
149+
const firstName = PersonContext.useSelector(state => state.firstName)
150+
151+
return <p>{firstName}</p>
152+
}
153+
```
154+
155+
#### useContext
156+
157+
This hook returns the entire context value.
158+
Use this instead of React.useContext for consistent behavior.
159+
160+
##### Examples
161+
162+
```tsx
163+
const MyComponent = () => {
164+
const person = PersonContext.useContext()
165+
// ...
166+
}
167+
```
168+
169+
#### useContextUpdate
170+
171+
This hook returns an update function that accepts a thunk function
172+
173+
Use this for a function that will change a value in
174+
[Concurrent Mode](https://reactjs.org/docs/concurrent-mode-intro.html).
175+
Otherwise, there's no need to use this hook.
176+
177+
##### Examples
178+
179+
```tsx
180+
const MyComponent = () => {
181+
const update = PersonContext.useContextUpdate()
182+
183+
update(() => setState(...));
184+
// ...
185+
}
186+
```
187+
188+
#### BridgeProvider
189+
190+
This is a Provider component for bridging multiple react roots
191+
192+
##### Parameters
193+
194+
- `$0` **[Object](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Object)**
195+
- `$0.context`
196+
- `$0.value`
197+
- `$0.children`
198+
199+
##### Examples
200+
201+
```tsx
202+
import { createContext } from 'react-easy-context-api'
203+
204+
type PersonContext = {
205+
firstName: string
206+
familyName: string
207+
}
208+
209+
const { Context, useBridgeValue, BridgeProvider } = createContext<PersonContext>({
210+
firstName: '',
211+
familyName: '',
212+
})
213+
214+
const App = () => {
215+
const valueToBridge = useBridgeValue()
216+
217+
return (
218+
<>
219+
<BridgeProvider context={Context} value={valueToBridge}>
220+
{children}
221+
</BridgeProvider>
222+
</>
223+
)
224+
}
225+
```
226+
227+
#### useBridgeValue
228+
229+
This hook return a value for BridgeProvider
230+
231+
## Limitations
232+
233+
- In order to stop propagation, `children` of a context provider has to be either created outside of the provider or memoized with `React.memo`.
234+
- Provider trigger re-renders only if the context value is referentially changed.
235+
- Neither context consumers or class components are supported.
236+
- The [stale props](https://react-redux.js.org/api/hooks#stale-props-and-zombie-children) issue can't be solved in userland.
237+
- Tearing is only avoided if all consumers get data using `useSelector`. If you use both props and selector to pass the same data, they may provide inconsistence data for a brief moment.
238+
239+
## Examples
240+
241+
Usage examples are being built.

grep

Lines changed: 0 additions & 100 deletions
This file was deleted.

0 commit comments

Comments
 (0)