Skip to content

Commit

Permalink
docs: Extended / updated documenation (#824)
Browse files Browse the repository at this point in the history
* Initial improvements, modernized react, add sandboxes

* touch
  • Loading branch information
mweststrate committed Jul 6, 2021
1 parent 7f41483 commit 847492c
Show file tree
Hide file tree
Showing 8 changed files with 315 additions and 170 deletions.
3 changes: 2 additions & 1 deletion .vscode/settings.json
@@ -1,5 +1,6 @@
{
"javascript.validate.enable": false,
"typescript.tsdk": "node_modules/typescript/lib",
"jest.enableInlineErrorMessages": true
"jest.enableInlineErrorMessages": true,
"cSpell.enabled": true
}
77 changes: 36 additions & 41 deletions website/docs/curried-produce.mdx
Expand Up @@ -9,7 +9,8 @@ title: Curried producers
data-ea-type="image"
className="horizontal bordered"
></div>
</center> <details>
</center>
<details>
<summary className="egghead-summary">
egghead.io lesson 6: Simplify code by using curried _reduce_
</summary>
Expand All @@ -30,56 +31,50 @@ title: Curried producers
</a>
</details>

Passing a function as the first argument to `produce` is intended to be used for currying. This means that you get a pre-bound producer that only needs a state to produce the value from. The producer function gets passed in the draft and any further arguments that were passed to the curried function.

For example:
Passing a function as the first argument to `produce` creates a function that doesn't apply `produce` yet to a specific state, but rather creates a function that will apply `produce` to any state that is passed to it in the future. This generally is called _currying_. Take for example the following example:

```javascript
// mapper will be of signature (state, index) => state
const mapper = produce((draft, index) => {
draft.index = index
})
import produce from "immer"

function toggleTodo(state, id) {
return produce(state, draft => {
const todo = draft.find(todo => todo.id === id)
todo.done = !todo.done
})
}

const baseState = [
{
id: "JavaScript",
title: "Learn TypeScript",
done: true
},
{
id: "Immer",
title: "Try Immer",
done: false
}
]

// example usage
console.dir([{}, {}, {}].map(mapper))
//[{index: 0}, {index: 1}, {index: 2}])
const nextState = toggleTodo(baseState, "Immer")
```

This mechanism can also nicely be leveraged to further simplify our example reducer:
The above pattern of `toggleTodo` is quite typical; pass an existing state to `produce`, modify the `draft`, and then return the result. Since `state` isn't used for anything else than passing it on to `produce`, the above example can be simplified by using the _curried_ form of `produce`, where you pass `produce` only the recipe function, and `produce` will return a new function that will apply recipe to the base state. This allows us to shorten the above `toggleTodo` definition.

```javascript
import produce from "immer"

const byId = produce((draft, action) => {
switch (action.type) {
case RECEIVE_PRODUCTS:
action.products.forEach(product => {
draft[product.id] = product
})
return
}
// curried producer:
const toggleTodo = produce((draft, id) => {
const todo = draft.find(todo => todo.id === id)
todo.done = !todo.done
})
```

Note that `state` is now factored out (the created reducer will accept a state, and invoke the bound producer with it).

If you want to initialize an uninitialized state using this construction, you can do so by passing the initial state as second argument to `produce`:

```javascript
import produce from "immer"
const baseState = [
/* as is */
]

const byId = produce(
(draft, action) => {
switch (action.type) {
case RECEIVE_PRODUCTS:
action.products.forEach(product => {
draft[product.id] = product
})
return
}
},
{
1: {id: 1, name: "product-1"}
}
)
const nextState = toggleTodo(baseState, "Immer")
```

Note that the `id` param has now become part of the recipe function! This pattern of having curried producers combines really neatly with for example the `useState` hook from React, as we will see on the next page.
79 changes: 0 additions & 79 deletions website/docs/example-reducer.mdx

This file was deleted.

0 comments on commit 847492c

Please sign in to comment.