Skip to content

Commit 0fcf242

Browse files
authored
Update README.md
1 parent ca1e03d commit 0fcf242

File tree

1 file changed

+47
-48
lines changed

1 file changed

+47
-48
lines changed

README.md

Lines changed: 47 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -13,8 +13,8 @@ Set of guidelines and patterns teaching how to fully leverage TypeScript feature
1313
- [React](#react)
1414
- [Class Component](#class-component)
1515
- [Stateless Component](#stateless-component)
16-
- [Redux Connected Component](#redux-connected-component)
1716
- [Higher-Order Component](#higher-order-component)
17+
- [Redux Connected Component](#redux-connected-component)
1818
- [Redux](#redux)
1919
- [Actions](#actions)
2020
- [Reducers](#reducers)
@@ -111,53 +111,6 @@ const MyComponent: React.StatelessComponent<Props> = (props) => {
111111
export default MyComponent;
112112
```
113113

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-
161114
## Higher-Order Component
162115
- decorate or wraps a component into another component
163116
- using Type Inference to automatically calculate Props interface for the resulting component
@@ -242,6 +195,52 @@ const ButtonWithFormItem = withFormItemDecorator(Button);
242195
...
243196
```
244197

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+
245244
---
246245

247246
# Redux

0 commit comments

Comments
 (0)