Skip to content

Commit c25d1f2

Browse files
authoredFeb 6, 2019
Merge pull request #83 from sw-yx/hooks-updates
updates for hooks
2 parents 36b24a0 + 1e0ee48 commit c25d1f2

File tree

1 file changed

+44
-0
lines changed

1 file changed

+44
-0
lines changed
 

‎README.md

+44
Original file line numberDiff line numberDiff line change
@@ -212,6 +212,32 @@ const [user, setUser] = useState<IUser | null>(null);
212212
setUser(newUser);
213213
```
214214

215+
**useRef**
216+
217+
When using `useRef`, you have two options when creating a ref container that does not have an initial value:
218+
219+
```ts
220+
const ref1 = useRef<HTMLElement>(null)
221+
const ref2 = useRef<HTMLElement | null>(null)
222+
```
223+
224+
The first option will make `ref1.current` read-only, and is intended to be passed in to built-in `ref` attributes that React will manage (because React handles setting the `current` value for you).
225+
226+
The second option will make `ref2.current` mutable, and is intended for "instance variables" that you manage yourself.
227+
228+
**useEffect**
229+
230+
When using `useEffect`, take care not to return anything other than a function or `undefined`, otherwise both TypeScript and React will yell at you. This can be subtle when using arrow functions:
231+
232+
```ts
233+
function DelayedEffect(props: { timerMs: number }) {
234+
// bad! setTimeout implicitly returns a number because the arrow function body isn't wrapped in curly braces
235+
const { timerMs } = props;
236+
useEffect(() => setTimeout(() => {/* do stuff */}, timerMs), [timerMs])
237+
return null
238+
}
239+
```
240+
215241
**Custom Hooks**
216242

217243
If you are returning an array in your Custom Hook, you will want to avoid type inference as Typescript will infer a union type (when you actually want different types in each position of the array). Instead, assert or define the function return types:
@@ -230,6 +256,24 @@ export function useLoading() {
230256
}
231257
```
232258

259+
A helper function that automatically types tuples can also be helpful if you write a lot of custom hooks:
260+
```ts
261+
function tuplify<T extends any[]>(...elements: T) { return elements }
262+
263+
function useArray() {
264+
const numberValue = useRef(3).current
265+
const functionValue = useRef(() => {}).current
266+
return [numberValue, functionValue] // type is (number | (() => void))[]
267+
}
268+
269+
function useTuple() {
270+
const numberValue = useRef(3).current
271+
const functionValue = useRef(() => {}).current
272+
return tuplify(numberValue, functionValue) // type is [number, () => void]
273+
}
274+
```
275+
The React team recommends that custom hooks that return more than two values should use proper objects instead of tuples, however.
276+
233277
If you are writing a React Hooks library, don't forget that you should also expose your types for users to use.
234278

235279
Example React Hooks + TypeScript Libraries:

0 commit comments

Comments
 (0)
Please sign in to comment.