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
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
+
returnnull
238
+
}
239
+
```
240
+
215
241
**Custom Hooks**
216
242
217
243
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() {
230
256
}
231
257
```
232
258
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<Textendsany[]>(...elements:T) { returnelements }
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
+
returntuplify(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
+
233
277
If you are writing a React Hooks library, don't forget that you should also expose your types for users to use.
0 commit comments