Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

docs: Extended / updated documenation #824

Merged
merged 4 commits into from Jul 6, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
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.