Skip to content

Commit bc7b862

Browse files
committed
docs(auto-effect): document auto effects
1 parent 3730075 commit bc7b862

1 file changed

Lines changed: 100 additions & 1 deletion

File tree

README.md

Lines changed: 100 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -479,7 +479,7 @@ export default view(() => {
479479
**Local stores in functions rely on React hooks. They require React and React DOM v16.8+ or React Native v0.59+ to work.**
480480

481481
<details>
482-
<summary>You can use any React hook - including <code>useState</code> - in function components, Easy State won't interfere with them.</summary>
482+
<summary>You can use React hooks - including <code>useState</code> - in function components, Easy State won't interfere with them. Please use [autoEffect](#local-auto-effects-in-function-components) instead of the `useEffect` hook for the best experience though.</summary>
483483
<p></p>
484484

485485
```jsx
@@ -623,6 +623,105 @@ Instead of returning an object, you should directly mutate the received stores.
623623

624624
</details>
625625

626+
### Adding side effects
627+
628+
Use `autoEffect` to react with automatic side effect to your store changes. Auto effects should contain end-of-chain logic - like changing the document title or saving data to LocalStorage. `view` is a special auto effect that does rendering.
629+
630+
<details>
631+
<summary>Never use auto effects to derive data from other data. Use dynamic getters instead.</summary>
632+
<p></p>
633+
634+
```jsx
635+
import { store, autoEffect } from 'react-easy-state';
636+
637+
// DON'T DO THIS
638+
const store1 = store({ name: 'Store 1' })
639+
const store2 = store({ name: 'Store 2' })
640+
autoEffect(() => store2.name = store1.name)
641+
642+
// DO THIS INSTEAD
643+
const store1 = store({ name: 'Store 1' })
644+
const store2 = store({ get name () { return store1.name } })
645+
```
646+
647+
</details>
648+
<p></p>
649+
650+
#### Global auto effects
651+
652+
Global auto effects can be created with `autoEffect` and cleared up with `clearEffect`.
653+
654+
```jsx
655+
import { store, autoEffect, clearEffect } from 'react-easy-state';
656+
657+
const app = store({ name: 'My App' })
658+
const effect = autoEffect(() => document.title = app.name)
659+
660+
// this also updates the document title
661+
app.name = 'My Awesome App'
662+
663+
clearEffect(effect)
664+
// this won't update the document title, the effect is cleared
665+
app.name = 'My App'
666+
```
667+
668+
#### Local auto effects in function components
669+
670+
Use local auto effects in function components instead of the `useEffect` hook when reactive stores are used inside them. These local effects are automatically cleared when the component unmounts.
671+
672+
```jsx
673+
import React from 'react'
674+
import { store, view, autoEffect } from 'react-easy-state';
675+
676+
export default view(() => {
677+
const app = store({ name: 'My App' })
678+
// no need to clear the effect
679+
autoEffect(() => document.title = app.name)
680+
})
681+
```
682+
683+
<details>
684+
<summary>Explicitly pass none reactive dependencies - like vanillas props and state - to local auto effects in function components.</summary>
685+
<p></p>
686+
687+
Because of the design of React hooks you have to explicitly pass all none reactive data to a hook-like dependency array. This makes sure that the effect also runs when the none reactive data changes.
688+
689+
```jsx
690+
import React from 'react'
691+
import { store, view, autoEffect } from 'react-easy-state';
692+
693+
export default view(({ greeting }) => {
694+
const app = store({ name: 'My App' })
695+
// pass `greeting` in the dependency array because it is not coming from a store
696+
autoEffect(() => document.title = `${greeting} ${app.name}`, [greeting])
697+
})
698+
```
699+
700+
</details>
701+
<p></p>
702+
703+
#### Local auto effects in class components
704+
705+
Local effects in class components must be cleared when the component unmounts.
706+
707+
```jsx
708+
import React, { Component } from 'react'
709+
import { store, view, autoEffect } from 'react-easy-state';
710+
711+
class App extends Component {
712+
app = store({ name: 'My App' })
713+
714+
componentDidMount () {
715+
this.effect = autoEffect(() => document.title = this.app.name)
716+
}
717+
718+
componentWillUnmount () {
719+
// local effects in class components must be cleared on unmount
720+
clearEffect(this.effect)
721+
}
722+
}
723+
```
724+
626725
---
627726

628727
## Examples with live demos

0 commit comments

Comments
 (0)