@@ -13,8 +13,8 @@ Set of guidelines and patterns teaching how to fully leverage TypeScript feature
13
13
- [ React] ( #react )
14
14
- [ Class Component] ( #class-component )
15
15
- [ Stateless Component] ( #stateless-component )
16
- - [ Redux Connected Component] ( #redux-connected-component )
17
16
- [ Higher-Order Component] ( #higher-order-component )
17
+ - [ Redux Connected Component] ( #redux-connected-component )
18
18
- [ Redux] ( #redux )
19
19
- [ Actions] ( #actions )
20
20
- [ Reducers] ( #reducers )
@@ -111,53 +111,6 @@ const MyComponent: React.StatelessComponent<Props> = (props) => {
111
111
export default MyComponent ;
112
112
```
113
113
114
- ## Redux Connected Component
115
- - This solution uses type inference to get Props types from ` mapStateToProps ` function
116
- - Minimise manual effort to declare and maintain Props types injected from ` connect ` helper function
117
- - Real project implementation example: https://github.com/piotrwitek/react-redux-typescript-starter-kit/blob/ef2cf6b5a2e71c55e18ed1e250b8f7cadea8f965/src/containers/currency-converter-container/index.tsx
118
-
119
- ``` tsx
120
- import { returntypeof } from ' react-redux-typescript' ;
121
-
122
- import { RootState } from ' ../../store' ;
123
- import { ActionCreators } from ' ../../store/currency-converter/reducer' ;
124
- import * as CurrencyRatesSelectors from ' ../../store/currency-rates/selectors' ;
125
-
126
- const mapStateToProps = (state : RootState ) => ({
127
- currencies: CurrencyRatesSelectors .getCurrencies (state ),
128
- currencyRates: storeState .currencyRates ,
129
- currencyConverter: storeState .currencyConverter ,
130
- });
131
-
132
- const dispatchToProps = {
133
- changeBaseCurrency: ActionCreators .changeBaseCurrency ,
134
- changeTargetCurrency: ActionCreators .changeTargetCurrency ,
135
- changeBaseValue: ActionCreators .changeBaseValue ,
136
- changeTargetValue: ActionCreators .changeTargetValue ,
137
- };
138
-
139
- const stateProps = returntypeof (mapStateToProps );
140
- type Props = typeof stateProps & typeof dispatchToProps ;
141
- // if needed to extend Props you can add an union with regular props (not injected) like this:
142
- // `type Props = typeof stateProps & typeof dispatchToProps & { className?: string, style?: object };`
143
- type State = {};
144
-
145
- class CurrencyConverterContainer extends React .Component <Props , State > {
146
- render() {
147
- // every destructured property below infer correct type from RootState!
148
- const { rates, base } = this .props .currencyRates ;
149
- const { baseCurrency, targetCurrency, baseValue, targetValue } = this .props .currencyConverter ;
150
- const {
151
- currencies, changeBaseCurrency, changeBaseValue, changeTargetCurrency, changeTargetValue,
152
- } = this .props ;
153
- ...
154
- }
155
- }
156
-
157
- export default connect (mapStateToProps , dispatchToProps )(CurrencyConverterContainer );
158
- ```
159
- ---
160
-
161
114
## Higher-Order Component
162
115
- decorate or wraps a component into another component
163
116
- using Type Inference to automatically calculate Props interface for the resulting component
@@ -242,6 +195,52 @@ const ButtonWithFormItem = withFormItemDecorator(Button);
242
195
...
243
196
```
244
197
198
+ ## Redux Connected Component
199
+ - This solution uses type inference to get Props types from ` mapStateToProps ` function
200
+ - Minimise manual effort to declare and maintain Props types injected from ` connect ` helper function
201
+ - Real project implementation example: https://github.com/piotrwitek/react-redux-typescript-starter-kit/blob/ef2cf6b5a2e71c55e18ed1e250b8f7cadea8f965/src/containers/currency-converter-container/index.tsx
202
+
203
+ ``` tsx
204
+ import { returntypeof } from ' react-redux-typescript' ;
205
+
206
+ import { RootState } from ' ../../store' ;
207
+ import { ActionCreators } from ' ../../store/currency-converter/reducer' ;
208
+ import * as CurrencyRatesSelectors from ' ../../store/currency-rates/selectors' ;
209
+
210
+ const mapStateToProps = (state : RootState ) => ({
211
+ counter: state .counter ,
212
+ baseCurrency: state .baseCurrency ,
213
+ currencies: CurrencyRatesSelectors .getCurrencies (state ),
214
+ });
215
+
216
+ const dispatchToProps = {
217
+ increaseCounter: ActionCreators .IncreaseCounter .create ,
218
+ changeBaseCurrency: ActionCreators .ChangeBaseCurrency .create ,
219
+ };
220
+
221
+ const stateProps = returntypeof (mapStateToProps );
222
+ type Props = typeof stateProps & typeof dispatchToProps ; // you can extend with more props
223
+ type State = {};
224
+
225
+ class CurrencyConverterContainer extends React .Component <Props , State > {
226
+ handleInputBlur = (ev : React .FocusEvent <HTMLInputElement >) => {
227
+ const parsedValue = parseInt (ev .currentTarget .value , 10 ); // string -> number
228
+ this .props .increaseCounter (parsedValue ); // number
229
+ }
230
+
231
+ handleSelectChange = (ev : React .ChangeEvent <HTMLSelectElement >) => {
232
+ this .props .changeBaseCurrency (ev .target .value ); // string
233
+ };
234
+
235
+ render() {
236
+ const { counter, baseCurrency, currencies } = this .props ; // number, string, string[]
237
+ ...
238
+ }
239
+ }
240
+
241
+ export default connect (mapStateToProps , dispatchToProps )(CurrencyConverterContainer );
242
+ ```
243
+
245
244
---
246
245
247
246
# Redux
0 commit comments