Repository navigation
Expand file tree
/
Copy pathUseReducerExample.tsx
More file actions
96 lines (90 loc) · 2.2 KB
/
Copy pathUseReducerExample.tsx
File metadata and controls
96 lines (90 loc) · 2.2 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
import React, { useReducer } from 'react';
import { entity, Shape, Recipe, recipeSafe } from '../index';
const personEntity = entity({
name: 'John Doe',
age: 20,
address: {
street: 'Some street 99',
zip: 1000,
country: 'Some country',
},
});
const nameAgeRecipe =
(
values: Partial<Pick<Shape<typeof personEntity>, 'name' | 'age'>>
): Recipe<typeof personEntity> =>
(entity) =>
entity.set(values);
const addressRecipe =
(
values: Partial<{
street: string;
zip: number;
country: string;
}>
): Recipe<typeof personEntity> =>
(entity) =>
entity.set({
address: { ...entity.get().address, ...values },
});
type Actions = typeof nameAgeRecipe | typeof addressRecipe;
export default function UseReducerExample() {
const [{ name, age, address }, dispatch] = useReducer(
(person, action: ReturnType<Actions>) =>
recipeSafe(person, action),
personEntity.getSafe()
);
return (
<div>
<h1>Object recipes: React useReducer() example</h1>
Name:{' '}
<input
type="text"
value={name}
onChange={({ currentTarget: { value } }) =>
dispatch(nameAgeRecipe({ name: value }))
}
/>
<br />
Age:{' '}
<input
type="text"
value={isNaN(age) ? '' : age.toString()}
onChange={({ currentTarget: { value } }) =>
dispatch(nameAgeRecipe({ age: parseInt(value) }))
}
/>
<br />
<br />
<b>Address</b>
<br />
Street:{' '}
<input
type="text"
value={address.street}
onChange={({ currentTarget: { value } }) =>
dispatch(addressRecipe({ street: value }))
}
/>
<br />
Zip:{' '}
<input
type="text"
value={isNaN(address.zip) ? '' : address.zip.toString()}
onChange={({ currentTarget: { value } }) =>
dispatch(addressRecipe({ zip: parseInt(value) }))
}
/>
<br />
Country:{' '}
<input
type="text"
value={address.country}
onChange={({ currentTarget: { value } }) =>
dispatch(addressRecipe({ country: value }))
}
/>
<br />
</div>
);
}