Skip to content

Commit 9dd8532

Browse files
authored
Merge pull request piotrwitek#78 from piotrwitek/playground-refactor
Playground refactor
2 parents 11c2c5a + a54ccd9 commit 9dd8532

30 files changed

+158
-183
lines changed

README.md

Lines changed: 46 additions & 73 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,9 @@ _"This guide is a **living compendium** documenting the most important patterns
2828
You should check Playground Project located in the `/playground` folder. It is a source of all the code examples found in the guide. They are all tested with the most recent version of TypeScript and 3rd party type definitions (like `@types/react` or `@types/react-redux`) to ensure the examples are up-to-date and not broken with updated definitions.
2929
> Playground was created is such a way, that you can simply clone the repository locally and immediately play around on your own to learn all the examples from this guide in a real project environment without the need to create some complicated environment setup by yourself.
3030
31+
### Contribution Guide
32+
[CONTRIBUTION.md](/CONTRIBUTION.md)
33+
3134
---
3235

3336
## Table of Contents
@@ -60,7 +63,6 @@ You should check Playground Project located in the `/playground` folder. It is a
6063
- [Vendor Types Augmentation](#vendor-types-augmentation)
6164
- [Default and Named Module Exports](#default-and-named-module-exports)
6265
- [FAQ](#faq)
63-
- [Contribution Guide](#contribution-guide)
6466
- [Tutorials](#tutorials)
6567

6668
---
@@ -505,8 +507,8 @@ export const withState = <WrappedProps extends InjectedProps>(
505507
```tsx
506508
import * as React from 'react';
507509

508-
import { withState } from '@src/hoc';
509-
import { SFCCounter } from '@src/components';
510+
import { withState } from '../hoc';
511+
import { SFCCounter } from '../components';
510512

511513
const SFCCounterWithState =
512514
withState(SFCCounter);
@@ -589,8 +591,8 @@ export const withErrorBoundary = <WrappedProps extends InjectedProps>(
589591
```tsx
590592
import * as React from 'react';
591593

592-
import { withErrorBoundary } from '@src/hoc';
593-
import { ErrorMessage } from '@src/components';
594+
import { withErrorBoundary } from '../hoc';
595+
import { ErrorMessage } from '../components';
594596

595597
const ErrorMessageWithErrorBoundary =
596598
withErrorBoundary(ErrorMessage);
@@ -633,14 +635,14 @@ const mapDispatchToProps = (dispatch: Dispatch) => ({
633635
#### - redux connected counter
634636
635637
```tsx
638+
import Types from 'Types';
636639
import { connect } from 'react-redux';
637640

638-
import { RootState } from '@src/redux';
639-
import { countersActions, countersSelectors } from '@src/redux/counters';
640-
import { SFCCounter } from '@src/components';
641+
import { countersActions, countersSelectors } from '../features/counters';
642+
import { SFCCounter } from '../components';
641643

642-
const mapStateToProps = (state: RootState) => ({
643-
count: countersSelectors.getReduxCounter(state),
644+
const mapStateToProps = (state: Types.RootState) => ({
645+
count: countersSelectors.getReduxCounter(state.counters),
644646
});
645647

646648
export const SFCCounterConnected = connect(mapStateToProps, {
@@ -653,7 +655,7 @@ export const SFCCounterConnected = connect(mapStateToProps, {
653655
```tsx
654656
import * as React from 'react';
655657

656-
import { SFCCounterConnected } from '@src/connected';
658+
import { SFCCounterConnected } from '../connected';
657659

658660
export default () => (
659661
<SFCCounterConnected
@@ -669,14 +671,14 @@ export default () => (
669671
#### - redux connected counter (verbose)
670672
671673
```tsx
672-
import { bindActionCreators } from 'redux';
674+
import Types from 'Types';
675+
import { bindActionCreators, Dispatch } from 'redux';
673676
import { connect } from 'react-redux';
674677

675-
import { RootState, Dispatch } from '@src/redux';
676-
import { countersActions } from '@src/redux/counters';
677-
import { SFCCounter } from '@src/components';
678+
import { countersActions } from '../features/counters';
679+
import { SFCCounter } from '../components';
678680

679-
const mapStateToProps = (state: RootState) => ({
681+
const mapStateToProps = (state: Types.RootState) => ({
680682
count: state.counters.reduxCounter,
681683
});
682684

@@ -693,7 +695,7 @@ export const SFCCounterConnectedVerbose =
693695
```tsx
694696
import * as React from 'react';
695697

696-
import { SFCCounterConnectedVerbose } from '@src/connected';
698+
import { SFCCounterConnectedVerbose } from '../connected';
697699

698700
export default () => (
699701
<SFCCounterConnectedVerbose
@@ -709,18 +711,18 @@ export default () => (
709711
#### - with own props
710712
711713
```tsx
714+
import Types from 'Types';
712715
import { connect } from 'react-redux';
713716

714-
import { RootState } from '@src/redux';
715-
import { countersActions, countersSelectors } from '@src/redux/counters';
716-
import { SFCCounter } from '@src/components';
717+
import { countersActions, countersSelectors } from '../features/counters';
718+
import { SFCCounter } from '../components';
717719

718720
export interface SFCCounterConnectedExtendedProps {
719721
initialCount: number;
720722
}
721723

722-
const mapStateToProps = (state: RootState, ownProps: SFCCounterConnectedExtendedProps) => ({
723-
count: countersSelectors.getReduxCounter(state) + ownProps.initialCount,
724+
const mapStateToProps = (state: Types.RootState, ownProps: SFCCounterConnectedExtendedProps) => ({
725+
count: countersSelectors.getReduxCounter(state.counters) + ownProps.initialCount,
724726
});
725727

726728
export const SFCCounterConnectedExtended = connect(mapStateToProps, {
@@ -733,7 +735,7 @@ export const SFCCounterConnectedExtended = connect(mapStateToProps, {
733735
```tsx
734736
import * as React from 'react';
735737

736-
import { SFCCounterConnectedExtended } from '@src/connected';
738+
import { SFCCounterConnectedExtended } from '../connected';
737739

738740
export default () => <SFCCounterConnectedExtended label={'SFCCounterConnectedExtended'} initialCount={10} />;
739741

@@ -756,7 +758,7 @@ export default () => <SFCCounterConnectedExtended label={'SFCCounterConnectedExt
756758
A solution below is using simple factory function to automate the creation of type-safe action creators. The goal is to reduce the maintainability and code repetition of type annotations for actions and creators and the result is completely typesafe action-creators and their actions.
757759
758760
```tsx
759-
import { action, createAction, createStandardAction } from 'typesafe-actions';
761+
import { action } from 'typesafe-actions';
760762

761763
import { ADD, INCREMENT } from './constants';
762764

@@ -770,10 +772,12 @@ export const add = (amount: number) => action(ADD, amount);
770772
// https://github.com/piotrwitek/typesafe-actions#behold-the-mighty-tutorial
771773

772774
// OPTION 1 (with generics):
775+
// import { createStandardAction } from 'typesafe-actions';
773776
// export const increment = createStandardAction(INCREMENT)<void>();
774777
// export const add = createStandardAction(ADD)<number>();
775778

776779
// OPTION 2 (with resolve callback):
780+
// import { createAction } from 'typesafe-actions';
777781
// export const increment = createAction(INCREMENT);
778782
// export const add = createAction(ADD, resolve => {
779783
// return (amount: number) => resolve(amount);
@@ -869,34 +873,20 @@ state.counterPairs[0].immutableCounter2 = 1; // TS Error: cannot be mutated
869873
870874
```tsx
871875
import { combineReducers } from 'redux';
872-
import { ActionsUnion } from 'typesafe-actions';
876+
import { ActionType } from 'typesafe-actions';
873877

874878
import { Todo, TodosFilter } from './models';
875879
import * as actions from './actions';
876880
import { ADD, CHANGE_FILTER, TOGGLE } from './constants';
877881

878882
export type TodosState = {
879-
readonly isFetching: boolean;
880-
readonly errorMessage: string | null;
881883
readonly todos: Todo[];
882884
readonly todosFilter: TodosFilter;
883885
};
884886

885-
export type TodosAction = ActionsUnion<typeof actions>;
887+
export type TodosAction = ActionType<typeof actions>;
886888

887889
export default combineReducers<TodosState, TodosAction>({
888-
isFetching: (state = false, action) => {
889-
switch (action.type) {
890-
default:
891-
return state;
892-
}
893-
},
894-
errorMessage: (state = null, action) => {
895-
switch (action.type) {
896-
default:
897-
return state;
898-
}
899-
},
900890
todos: (state = [], action) => {
901891
switch (action.type) {
902892
case ADD:
@@ -1010,21 +1000,21 @@ When creating a store instance we don't need to provide any additional types. It
10101000
> The resulting store instance methods like `getState` or `dispatch` will be type checked and will expose all type errors
10111001
10121002
```tsx
1013-
import { createStore, applyMiddleware, compose } from 'redux';
1003+
import { createStore, applyMiddleware } from 'redux';
10141004
import { createEpicMiddleware } from 'redux-observable';
10151005

1006+
import { composeEnhancers } from './utils';
10161007
import rootReducer from './root-reducer';
10171008
import rootEpic from './root-epic';
1009+
import services from '../services';
10181010

1019-
const composeEnhancers =
1020-
(process.env.NODE_ENV === 'development' &&
1021-
window &&
1022-
window.__REDUX_DEVTOOLS_EXTENSION_COMPOSE__) ||
1023-
compose;
1011+
export const epicMiddleware = createEpicMiddleware(rootEpic, {
1012+
dependencies: services,
1013+
});
10241014

10251015
function configureStore(initialState?: object) {
10261016
// configure middlewares
1027-
const middlewares = [createEpicMiddleware(rootEpic)];
1017+
const middlewares = [epicMiddleware];
10281018
// compose enhancers
10291019
const enhancer = composeEnhancers(applyMiddleware(...middlewares));
10301020
// create store
@@ -1048,7 +1038,6 @@ export default store;
10481038
### For more examples and in-depth explanation you should read [The Mighty Tutorial](https://github.com/piotrwitek/typesafe-actions#behold-the-mighty-tutorial) to learn it all the easy way!
10491039
10501040
```tsx
1051-
// tslint:disable:no-console
10521041
import Types from 'Types';
10531042
import { combineEpics, Epic } from 'redux-observable';
10541043
import { tap, ignoreElements, filter } from 'rxjs/operators';
@@ -1059,12 +1048,13 @@ import { todosConstants, TodosAction } from '../todos';
10591048
// contrived example!!!
10601049
const logAddAction: Epic<TodosAction, Types.RootState, Types.Services> = (
10611050
action$,
1062-
store
1051+
store,
1052+
{ logger }
10631053
) =>
10641054
action$.pipe(
10651055
filter(isOfType(todosConstants.ADD)), // action is narrowed to: { type: "ADD_TODO"; payload: string; }
10661056
tap(action => {
1067-
console.log(
1057+
logger.log(
10681058
`action type must be equal: ${todosConstants.ADD} === ${action.type}`
10691059
);
10701060
}),
@@ -1447,33 +1437,16 @@ class StatefulCounter extends React.Component<Props, State> {
14471437
14481438
---
14491439
1450-
# Contribution Guide
1451-
- Don't edit `README.md` - it is built with `generator` script from separate `.md` files located in the `/docs/markdown` folder, edit them instead
1452-
- For code snippets, they are also injected by `generator` script from the source files located in the playground folder (this step make sure all examples are type-checked and linted), edit them instead
1453-
> look for include directives in `.md` files that look like this: `::[example|usage]='../../playground/src/components/sfc-counter.tsx'::`
1454-
1455-
Before opening PR please make sure to check:
1456-
```bash
1457-
# run linter in playground
1458-
yarn run lint
1459-
1460-
# run type-checking in playground
1461-
yarn run tsc
1462-
1463-
# re-generate `README.md` from repo root
1464-
sh ./generate.sh
1465-
# or
1466-
node ./generator/bin/generate-readme.js
1467-
```
1468-
1469-
[⇧ back to top](#table-of-contents)
1470-
1471-
---
1472-
14731440
# Tutorials
14741441
> Curated list of relevant in-depth tutorials
14751442
14761443
Higher-Order Components:
14771444
- https://medium.com/@jrwebdev/react-higher-order-component-patterns-in-typescript-42278f7590fb
14781445
14791446
[⇧ back to top](#table-of-contents)
1447+
1448+
---
1449+
1450+
MIT License
1451+
1452+
Copyright (c) 2017 Piotr Witek <[email protected]> (http://piotrwitek.github.io)

docs/markdown/_intro.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,3 +27,6 @@ _"This guide is a **living compendium** documenting the most important patterns
2727

2828
You should check Playground Project located in the `/playground` folder. It is a source of all the code examples found in the guide. They are all tested with the most recent version of TypeScript and 3rd party type definitions (like `@types/react` or `@types/react-redux`) to ensure the examples are up-to-date and not broken with updated definitions.
2929
> Playground was created is such a way, that you can simply clone the repository locally and immediately play around on your own to learn all the examples from this guide in a real project environment without the need to create some complicated environment setup by yourself.
30+
31+
### Contribution Guide
32+
[CONTRIBUTION.md](/CONTRIBUTION.md)

playground/package-lock.json

Lines changed: 18 additions & 18 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

playground/package.json

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -25,24 +25,24 @@
2525
"dependencies": {
2626
"axios": "0.18.0",
2727
"cuid": "2.1.1",
28-
"react": "16.3.2",
29-
"react-dom": "16.3.2",
28+
"react": "16.4.0",
29+
"react-dom": "16.4.0",
3030
"react-redux": "5.0.7",
3131
"react-router-dom": "4.2.2",
3232
"react-router-redux": "5.0.0-alpha.8",
3333
"redux": "4.0.0",
3434
"redux-observable": "1.0.0-alpha.2",
3535
"reselect": "3.0.1",
36-
"rxjs": "6.1.0",
37-
"rxjs-compat": "6.1.0",
36+
"rxjs": "6.2.0",
37+
"rxjs-compat": "6.2.0",
3838
"tslib": "1.9.1",
39-
"typesafe-actions": "2.0.3",
39+
"typesafe-actions": "2.0.4",
4040
"utility-types": "2.0.0"
4141
},
4242
"devDependencies": {
4343
"@types/enzyme": "3.1.10",
4444
"@types/jest": "22.2.3",
45-
"@types/prop-types": "15.5.2",
45+
"@types/prop-types": "15.5.3",
4646
"@types/react": "16.3.14",
4747
"@types/react-dom": "16.0.5",
4848
"@types/react-redux": "6.0.0",

0 commit comments

Comments
 (0)