Skip to content

Commit b525db0

Browse files
authored
Add simple reducer example
1 parent 12331d2 commit b525db0

File tree

1 file changed

+98
-0
lines changed

1 file changed

+98
-0
lines changed

pages/docs/manual/v9.0.0/newcomer-examples.mdx

Lines changed: 98 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -132,3 +132,101 @@ function greetByName(possiblyNullName) {
132132
</CodeTab>
133133

134134
This check compiles to `possiblyNullName == null` in JS, so checks for the presence of `null` or `undefined`.
135+
136+
## Modeling reducers
137+
138+
A reducer is a function that accepts in some state and an action and returns a new state. In ReScript, you can model the state and the action as separate types.
139+
140+
### Modeling state
141+
142+
For modeling the state type, it's best to use a record over an object type:
143+
144+
<CodeTab labels={["ReScript", "JS Output"]}>
145+
146+
```res example
147+
type countType = {
148+
count: int
149+
}
150+
151+
let reducer = ({ count }: countType, _): countType => {
152+
{ count: count + 1 }
153+
}
154+
```
155+
```js
156+
function reducer(param, param$1) {
157+
return {
158+
count: param.count + 1 | 0
159+
};
160+
}
161+
```
162+
163+
</CodeTab>
164+
165+
When you need to store a dictionary of values, try using the `Belt.Map` type. The `Belt` library contains safe methods for working with immutable data structures (they won't throw errors):
166+
167+
<CodeTab labels={["ReScript", "JS Output"]}>
168+
169+
```res example
170+
open Belt
171+
172+
type todo = {
173+
id: string,
174+
name: string,
175+
completed: bool
176+
}
177+
178+
type state = {
179+
todos: Map.String.t<todo>
180+
}
181+
182+
// Example of a function that adds a todo. We use the `Belt.Map.String.set`
183+
// function to add the todo to the todos map.
184+
let addTodo = (state: state, todo: todo): state => {
185+
{...state, todos: state.todos->Map.String.set(todo.id, todo)}
186+
}
187+
```
188+
```js
189+
function addTodo(state, todo) {
190+
return {
191+
todos: Belt_MapString.set(state.todos, todo.id, todo)
192+
};
193+
}
194+
```
195+
196+
</CodeTab>
197+
198+
## Modeling actions
199+
200+
For smaller reducers (reducers with only a few sub-functions), you can use a variant for your action type. You can use a `switch` statement to pattern match on the different action types. Here's an example of a reducer for a simple counter:
201+
202+
```res example
203+
type state = {
204+
count: int
205+
}
206+
207+
type action =
208+
| Increment
209+
| Decrement
210+
211+
let reducer = (state: state, action: action): state => {
212+
switch action {
213+
| Increment => { count: state.count + 1 }
214+
| Decrement => { count: state.count - 1 }
215+
}
216+
}
217+
```
218+
```js
219+
function reducer(state, action) {
220+
if (action) {
221+
return {
222+
count: state.count - 1 | 0
223+
};
224+
} else {
225+
return {
226+
count: state.count + 1 | 0
227+
};
228+
}
229+
}
230+
```
231+
232+
</CodeTab>

0 commit comments

Comments
 (0)