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
If you have state that can be derived from state then you can use the [`select`](#select(selector)) helper. Simply attach it to any part of your model.
252
+
If you have state that can be derived from state then you can use the [`select`](#selectselector) helper. Simply attach it to any part of your model.
253
253
254
254
```javascript
255
255
import { select } from'easy-peasy'; // 👈 import then helper
@@ -290,6 +290,10 @@ Oh! And don't forget to install the [Redux Dev Tools Extension](https://github.c
290
290
291
291
## Usage with React
292
292
293
+
With the new [Hooks](https://reactjs.org/docs/hooks-intro.html) feature introduced in React v16.7.0 it's never been easier to provide a mechanism to interact with global state in your components. We have provided two hooks, allowing you to access the state and actions from your store.
294
+
295
+
If you aren't familiar with hooks yet we highly recommend that you read the [official documentation](https://reactjs.org/docs/hooks-intro.html) and try playing with our [examples](#examples). Hooks are truly game changing and will simplify your components dramatically.
296
+
293
297
### Wrap your app with StoreProvider
294
298
295
299
Firstly we will need to create your store and wrap your application with the `StoreProvider`.
@@ -309,7 +313,7 @@ const App = () => (
309
313
310
314
### Consuming state in your Components
311
315
312
-
In order to use state within your components you can use the `useStore` hook.
316
+
To access state within your components you can use the `useStore` hook.
313
317
314
318
```javascript
315
319
import { useStore } from'easy-peasy';
@@ -324,6 +328,8 @@ const TodoList = () => {
324
328
};
325
329
```
326
330
331
+
It's almost too easy that it doesn't require much explanation. We do however recommend that you read the API docs for the [`useStore` hook](#usestoremapstate) to gain a full understanding of the behaviours and pitfalls of the hook.
332
+
327
333
### Firing actions in your Components
328
334
329
335
In order to fire actions in your components you can use the `useAction` hook.
@@ -344,6 +350,8 @@ const AddTodo = () => {
344
350
};
345
351
```
346
352
353
+
For more on how you can use this hook please ready the API docs for the [`useAction` hook](#useactionmapaction).
354
+
347
355
### Alternative usage via react-redux
348
356
349
357
As Easy Peasy outputs a standard Redux store it is entirely possible to use Easy Peasy with the official [`react-redux`](https://github.com/reduxjs/react-redux) package.
@@ -641,42 +649,17 @@ A [hook](https://reactjs.org/docs/hooks-intro.html) granting your components acc
641
649
642
650
#### Arguments
643
651
644
-
You need to provide it with a function which is used to resolved the piece of state that your component requires. The function will receive the store's state and requires you to return back the piece of state you require.
645
-
646
-
You can either return a single value of state, or if you like an object containing multiple mappings of state (which is similar to the `connect` from `react-redux`).
647
-
648
-
For example, single piece of state:
649
-
650
-
```javascript
651
-
constage=useStore(state=>state.user.age)
652
-
```
653
-
654
-
Or, multiple pieces of state via an object:
652
+
- `mapState` (Function, required)
655
653
656
-
```javascript
657
-
const { age, theme } =useStore(state=> ({
658
-
age:state.user.age,
659
-
theme:state.preferences.theme
660
-
}));
661
-
```
662
-
663
-
#### A word of caution
654
+
The function that is used to resolved the piece of state that your component requires. The function will receive the following arguments:
664
655
665
-
Please be careful in the manner that you map the state. Under the hood we use equality checking (===), similar to `react-redux` to determine if the mapped state has changed. If the equality check fails then your component will be "notified" of the change, receiving the updated state.
666
-
667
-
For example, wrapping your mapped state in an array is a bad idea as every time we tried to map your state a new array instance would be created and therefore the equality check would always break.
The only exception to the rule above is the case where you return an object against which you map multiple pieces of state. In this case we fall back to a shallow equality check between the old and new states before notifying your component of the changed state.
658
+
The root state of your store.
676
659
677
-
So, rule of thumb is to never dervive new values/state within your mapState function. Remember you can leverage the (`select`)(#selectselector) helper against your store to help with derived state.
660
+
Your `mapState` can either resolve a single piece of state. If you wish to resolve multiple pieces of state then you can either call `useStore` multiple times, or if you like resolve an object within your `mapState` where each property of the object is a resolved piece of state (similar to the `connect` from `react-redux`). The examples will illustrate the various forms.
678
661
679
-
####Example
662
+
####Example
680
663
681
664
```javascript
682
665
import { useStore } from'easy-peasy';
@@ -691,7 +674,7 @@ const TodoList = () => {
691
674
};
692
675
```
693
676
694
-
If you wish to access multiple pieces of state in the same component you can make multiple calls to `useStore`.
677
+
#### Example resolving multiple values
695
678
696
679
```javascript
697
680
import { useStore } from'easy-peasy';
@@ -708,9 +691,83 @@ const BasketTotal = () => {
708
691
};
709
692
```
710
693
711
-
### useAction
694
+
#### Example resolving multiple values via an object result
Please be careful in the manner that you resolve values from your `mapToState`. To optimise the rendering performance of your components we use equality checking (===) to determine if the mapped state has changed.
716
+
717
+
When an action changes the piece of state your `mapState` is resolving the equality check will break, which will cause your component to re-render with the new state.
718
+
719
+
Therefore deriving state within your `mapState` in a manner that will always produce a new value (for e.g. an array) is an anti-pattern as it will break our equality checks.
720
+
721
+
```javascript
722
+
// ❗️ Using .map will produce a new array instance every time mapState is called
Note, the same rule applies when you are using the object result form of `mapState`:
748
+
749
+
```javascript
750
+
const { productNames, total } =useStore(state=> ({
751
+
productNames:state.products.map(x=>x.name), // ❗️ new array every time
752
+
total:state.basket.total
753
+
}));
754
+
```
755
+
756
+
### useAction(mapAction)
712
757
713
-
A [hook](https://reactjs.org/docs/hooks-intro.html) granting your components access to the store's actions. You need to provide it with a function which is used to resolved the action that your component requires.
758
+
A [hook](https://reactjs.org/docs/hooks-intro.html) granting your components access to the store's actions.
759
+
760
+
#### Arguments
761
+
762
+
- `mapAction` (Function, required)
763
+
764
+
The function that is used to resolved the action that your component requires. The function will receive the following arguments:
765
+
766
+
- `dispatch` (Object, required)
767
+
768
+
The `dispatch` of your store, which has all the actions mapped against it.
769
+
770
+
Your `mapAction` can either resolve a single action. If you wish to resolve multiple actions then you can either call `useAction` multiple times, or if you like resolve an object within your `mapAction` where each property of the object is a resolved action. The examples below will illustrate these options.
714
771
715
772
#### Example
716
773
@@ -730,7 +787,27 @@ const AddTodo = () => {
730
787
};
731
788
```
732
789
733
-
If you wish to access multiple actions in the same component you can make multiple calls to `useAction`.
790
+
#### Example resolving multiple actions via an object map
0 commit comments