Skip to content

Commit

Permalink
docs: add withInit
Browse files Browse the repository at this point in the history
  • Loading branch information
artalar committed Aug 30, 2024
1 parent 15e2dc7 commit 08438cf
Show file tree
Hide file tree
Showing 2 changed files with 104 additions and 16 deletions.
60 changes: 52 additions & 8 deletions docs/src/content/docs/package/hooks.md
Original file line number Diff line number Diff line change
Expand Up @@ -49,10 +49,10 @@ For example, in React you should manage abort strategy by yourself by `useEffect
import { reatomAsync, withAbort, withDataAtom } from '@reatom/async'
import { useAtom, useAction } from '@reatom/npm-react'

export const fetchList = reatomAsync(
(ctx) => request('api/list', ctx.controller),
'fetchList',
).pipe(withAbort(), withDataAtom([]))
export const fetchList = reatomAsync((ctx) => request('api/list', ctx.controller), 'fetchList').pipe(
withAbort(),
withDataAtom([]),
)

export const List = () => {
const [list] = useAtom(fetchList.dataAtom)
Expand All @@ -74,10 +74,7 @@ With Reatom, you can simplify it and make it more readable.
import { reatomAsync, onConnect, withDataAtom } from '@reatom/framework'
import { useAtom } from '@reatom/npm-react'

export const fetchList = reatomAsync(
(ctx) => request('api/list', ctx.controller),
'fetchList',
).pipe(withDataAtom([]))
export const fetchList = reatomAsync((ctx) => request('api/list', ctx.controller), 'fetchList').pipe(withDataAtom([]))
onConnect(fetchList.dataAtom, fetchList)

export const List = () => {
Expand All @@ -93,6 +90,53 @@ Isn't it cool, how the size of the code is reduced and how the logic is simplifi

Shortcut to `onConnect` returned callback.

## withInit

This operator helps you to initialize the state lazily on the first atom read.

```ts
import { atom } from '@reatom/core'
import { withInit } from '@reatom/hooks'

export const langAtom = atom('', 'langAtom').pipe(
withInit(() => navigator.languages?.[0] ?? (navigator.language || navigator.userLanguage)),
)
```

You can use it to depend the init state from an other atom too.

```ts
import { atom } from '@reatom/core'
import { withInit } from '@reatom/hooks'

export const pageTitleAtom = atom('', 'pageTitleAtom')

export const searchAtom = atom('', 'searchAtom').pipe(withInit((ctx) => ctx.get(pageTitleAtom)))
```

Also, you can use it to do a side effects in rare cases.

```ts
export const pageUptimeAtom = atom(0, 'pageUptimeAtom').pipe(
withInit((ctx) => {
setTimeout(() => pageUptimeAtom(ctx, performance.now()), 1000)
return performance.now()
}),
)
```

```ts
export const dataAtom = atom(0, 'dataAtom').pipe(
withInit((ctx, init) => {
ctx.get(socketServiceAtom).on('data', (data) => dataAtom(ctx, data))

return init(ctx)
}),
)
```

Note that the subscription will leave forever. To manage resources more efficiently, you can use should use probably [onConnect](#onconnect).

## isInit

This utility allows you to check that the current atom or action is being called for the first time (in the current context). It is useful to perform some initialisation effects only once.
Expand Down
60 changes: 52 additions & 8 deletions packages/hooks/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -40,10 +40,10 @@ For example, in React you should manage abort strategy by yourself by `useEffect
import { reatomAsync, withAbort, withDataAtom } from '@reatom/async'
import { useAtom, useAction } from '@reatom/npm-react'

export const fetchList = reatomAsync(
(ctx) => request('api/list', ctx.controller),
'fetchList',
).pipe(withAbort(), withDataAtom([]))
export const fetchList = reatomAsync((ctx) => request('api/list', ctx.controller), 'fetchList').pipe(
withAbort(),
withDataAtom([]),
)

export const List = () => {
const [list] = useAtom(fetchList.dataAtom)
Expand All @@ -65,10 +65,7 @@ With Reatom, you can simplify it and make it more readable.
import { reatomAsync, onConnect, withDataAtom } from '@reatom/framework'
import { useAtom } from '@reatom/npm-react'

export const fetchList = reatomAsync(
(ctx) => request('api/list', ctx.controller),
'fetchList',
).pipe(withDataAtom([]))
export const fetchList = reatomAsync((ctx) => request('api/list', ctx.controller), 'fetchList').pipe(withDataAtom([]))
onConnect(fetchList.dataAtom, fetchList)

export const List = () => {
Expand All @@ -84,6 +81,53 @@ Isn't it cool, how the size of the code is reduced and how the logic is simplifi

Shortcut to `onConnect` returned callback.

## withInit

This operator helps you to initialize the state lazily on the first atom read.

```ts
import { atom } from '@reatom/core'
import { withInit } from '@reatom/hooks'

export const langAtom = atom('', 'langAtom').pipe(
withInit(() => navigator.languages?.[0] ?? (navigator.language || navigator.userLanguage)),
)
```

You can use it to depend the init state from an other atom too.

```ts
import { atom } from '@reatom/core'
import { withInit } from '@reatom/hooks'

export const pageTitleAtom = atom('', 'pageTitleAtom')

export const searchAtom = atom('', 'searchAtom').pipe(withInit((ctx) => ctx.get(pageTitleAtom)))
```

Also, you can use it to do a side effects in rare cases.

```ts
export const pageUptimeAtom = atom(0, 'pageUptimeAtom').pipe(
withInit((ctx) => {
setTimeout(() => pageUptimeAtom(ctx, performance.now()), 1000)
return performance.now()
}),
)
```

```ts
export const dataAtom = atom(0, 'dataAtom').pipe(
withInit((ctx, init) => {
ctx.get(socketServiceAtom).on('data', (data) => dataAtom(ctx, data))

return init(ctx)
}),
)
```

Note that the subscription will leave forever. To manage resources more efficiently, you can use should use probably [onConnect](#onconnect).

## isInit

This utility allows you to check that the current atom or action is being called for the first time (in the current context). It is useful to perform some initialisation effects only once.
Expand Down

0 comments on commit 08438cf

Please sign in to comment.