diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 6fe5a9c..a7d55d1 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -22,8 +22,8 @@ Don't edit `README.md` directly - it is generated automatically from `README_SOU **Source code inject directives:** ``` # Inject code block with highlighter -::codeblock='playground/src/components/sfc-counter.tsx':: +::codeblock='playground/src/components/fc-counter.tsx':: # Inject code block with highlighter and expander -::expander='playground/src/components/sfc-counter.usage.tsx':: +::expander='playground/src/components/fc-counter.usage.tsx':: ``` diff --git a/README.md b/README.md index 66649a6..6cd28f3 100644 --- a/README.md +++ b/README.md @@ -46,8 +46,8 @@ This gives you the power to prioritize our work and support the project contribu - [Type Definitions & Complementary Libraries](#type-definitions--complementary-libraries) - [React Types Cheatsheet](#react-types-cheatsheet) 🌟 __NEW__ - [Component Typing Patterns](#component-typing-patterns) - - [Stateless Components - SFC](#stateless-components---sfc) - - [Stateful Components - Class](#stateful-components---class) 📝 __UPDATED__ + - [Function Components - FC](#function-components---fc) + - [Class Components ](#class-components) 📝 __UPDATED__ - [Generic Components](#generic-components) - [Render Props](#render-props) 🌟 __NEW__ - [Higher-Order Components](#higher-order-components) 📝 __UPDATED__ @@ -106,22 +106,22 @@ npm i -D @types/react @types/react-dom @types/react-redux # React Types Cheatsheet -#### `React.StatelessComponent

` or `React.SFC

` -Type representing stateless functional component +#### `React.FunctionComponent

` or `React.FC

` +Type representing a functional component ```tsx -const MyComponent: React.SFC = ... +const MyComponent: React.FC = ... ``` [⇧ back to top](#table-of-contents) #### `React.Component` -Type representing stateful class component +Type representing a class component ```tsx class MyComponent extends React.Component { ... ``` [⇧ back to top](#table-of-contents) #### `React.ComponentType

` -Type representing union type of (SFC | Component) +Type representing union type of (FC | Component) ```tsx const withState =

( WrappedComponent: React.ComponentType

, @@ -174,27 +174,31 @@ const handleChange = (ev: React.MouseEvent) => { ... } # Component Typing Patterns -## Stateless Components - SFC +## Function Components - FC -#### - stateless counter +#### - FC counter ```tsx import * as React from 'react'; -export interface SFCCounterProps { +type Props = { label: string; count: number; onIncrement: () => any; -} +}; -export const SFCCounter: React.SFC = (props) => { +export const FCCounter: React.FC = props => { const { label, count, onIncrement } = props; - const handleIncrement = () => { onIncrement(); }; + const handleIncrement = () => { + onIncrement(); + }; return (

- {label}: {count} + + {label}: {count}{' '} + @@ -204,7 +208,7 @@ export const SFCCounter: React.SFC = (props) => { ``` -[⟩⟩⟩ demo](https://piotrwitek.github.io/react-redux-typescript-guide/#sfccounter) +[⟩⟩⟩ demo](https://piotrwitek.github.io/react-redux-typescript-guide/#fccounter) [⇧ back to top](#table-of-contents) @@ -213,52 +217,48 @@ export const SFCCounter: React.SFC = (props) => { ```tsx import * as React from 'react'; -export interface SFCSpreadAttributesProps { +type Props = { className?: string; style?: React.CSSProperties; -} +}; -export const SFCSpreadAttributes: React.SFC = (props) => { +export const FCSpreadAttributes: React.FC = props => { const { children, ...restProps } = props; - return ( -
- {children} -
- ); + return
{children}
; }; ``` -[⟩⟩⟩ demo](https://piotrwitek.github.io/react-redux-typescript-guide/#sfcspreadattributes) +[⟩⟩⟩ demo](https://piotrwitek.github.io/react-redux-typescript-guide/#fcspreadattributes) [⇧ back to top](#table-of-contents) --- -## Stateful Components - Class +## Class Components -#### - stateful counter +#### - class counter ```tsx import * as React from 'react'; -export interface StatefulCounterProps { +type Props = { label: string; -} +}; -interface State { - readonly count: number; -} +type State = { + count: number; +}; -export class StatefulCounter extends React.Component { +export class ClassCounter extends React.Component { readonly state: State = { count: 0, }; handleIncrement = () => { this.setState({ count: this.state.count + 1 }); - } + }; render() { const { handleIncrement } = this; @@ -267,7 +267,9 @@ export class StatefulCounter extends React.Component - {label}: {count} + + {label}: {count}{' '} + @@ -278,7 +280,7 @@ export class StatefulCounter extends React.Component; +}; -type State = Readonly<{ +type State = { count: number; -}>; +}; -export class StatefulCounterWithDefault extends React.Component { +export class ClassCounterWithDefaultProps extends React.Component< + Props, + State +> { static defaultProps = { initialCount: 0, }; @@ -335,7 +340,7 @@ export class StatefulCounterWithDefault extends React.Component { ``` -[⟩⟩⟩ demo](https://piotrwitek.github.io/react-redux-typescript-guide/#statefulcounterwithdefault) +[⟩⟩⟩ demo](https://piotrwitek.github.io/react-redux-typescript-guide/#classcounterwithdefaultprops) [⇧ back to top](#table-of-contents) @@ -516,14 +521,11 @@ export const withState = ( import * as React from 'react'; import { withState } from '../hoc'; -import { SFCCounter } from '../components'; +import { FCCounter } from '../components'; -const SFCCounterWithState = - withState(SFCCounter); +const FCCounterWithState = withState(FCCounter); -export default () => ( - -); +export default () => ; ```

@@ -647,15 +649,18 @@ import Types from 'Types'; import { connect } from 'react-redux'; import { countersActions, countersSelectors } from '../features/counters'; -import { SFCCounter } from '../components'; +import { FCCounter } from '../components'; const mapStateToProps = (state: Types.RootState) => ({ count: countersSelectors.getReduxCounter(state.counters), }); -export const SFCCounterConnected = connect(mapStateToProps, { - onIncrement: countersActions.increment, -})(SFCCounter); +export const FCCounterConnected = connect( + mapStateToProps, + { + onIncrement: countersActions.increment, + } +)(FCCounter); ```
Click to expand

@@ -663,13 +668,9 @@ export const SFCCounterConnected = connect(mapStateToProps, { ```tsx import * as React from 'react'; -import { SFCCounterConnected } from '../connected'; +import { FCCounterConnected } from '.'; -export default () => ( - -); +export default () => ; ```

@@ -684,18 +685,24 @@ import { bindActionCreators, Dispatch } from 'redux'; import { connect } from 'react-redux'; import { countersActions } from '../features/counters'; -import { SFCCounter } from '../components'; +import { FCCounter } from '../components'; const mapStateToProps = (state: Types.RootState) => ({ count: state.counters.reduxCounter, }); -const mapDispatchToProps = (dispatch: Dispatch) => bindActionCreators({ - onIncrement: countersActions.increment, -}, dispatch); +const mapDispatchToProps = (dispatch: Dispatch) => + bindActionCreators( + { + onIncrement: countersActions.increment, + }, + dispatch + ); -export const SFCCounterConnectedVerbose = - connect(mapStateToProps, mapDispatchToProps)(SFCCounter); +export const FCCounterConnectedVerbose = connect( + mapStateToProps, + mapDispatchToProps +)(FCCounter); ```
Click to expand

@@ -703,12 +710,10 @@ export const SFCCounterConnectedVerbose = ```tsx import * as React from 'react'; -import { SFCCounterConnectedVerbose } from '../connected'; +import { FCCounterConnectedVerbose } from '.'; export default () => ( - + ); ``` @@ -723,19 +728,23 @@ import Types from 'Types'; import { connect } from 'react-redux'; import { countersActions, countersSelectors } from '../features/counters'; -import { SFCCounter } from '../components'; +import { FCCounter } from '../components'; -export interface SFCCounterConnectedExtendedProps { +type OwnProps = { initialCount: number; -} +}; -const mapStateToProps = (state: Types.RootState, ownProps: SFCCounterConnectedExtendedProps) => ({ - count: countersSelectors.getReduxCounter(state.counters) + ownProps.initialCount, +const mapStateToProps = (state: Types.RootState, ownProps: OwnProps) => ({ + count: + countersSelectors.getReduxCounter(state.counters) + ownProps.initialCount, }); -export const SFCCounterConnectedExtended = connect(mapStateToProps, { - onIncrement: countersActions.increment, -})(SFCCounter); +export const FCCounterConnectedExtended = connect( + mapStateToProps, + { + onIncrement: countersActions.increment, + } +)(FCCounter); ```

Click to expand

@@ -743,9 +752,14 @@ export const SFCCounterConnectedExtended = connect(mapStateToProps, { ```tsx import * as React from 'react'; -import { SFCCounterConnectedExtended } from '../connected'; +import { FCCounterConnectedExtended } from '.'; -export default () => ; +export default () => ( + +); ```

@@ -1171,7 +1185,7 @@ export const getFilteredTodos = createSelector(getTodos, getTodosFilter, (todos, ## Typing connect Below snippet can be find in the `playground/` folder, you can checkout the repo and follow all dependencies to understand the bigger picture. -`playground/src/connected/sfc-counter-connected-verbose.tsx` +`playground/src/connected/fc-counter-connected-verbose.tsx` ```tsx import Types from 'Types'; @@ -1180,10 +1194,10 @@ import { bindActionCreators, Dispatch } from 'redux'; import { connect } from 'react-redux'; import { countersActions } from '../features/counters'; -import { SFCCounter, SFCCounterProps } from '../components'; +import { FCCounter } from '../components'; // `state` parameter needs a type annotation to type-check the correct shape of a state object but also it'll be used by "type inference" to infer the type of returned props -const mapStateToProps = (state: Types.RootState, ownProps: SFCCounterProps) => ({ +const mapStateToProps = (state: Types.RootState, ownProps: FCCounterProps) => ({ count: state.counters.reduxCounter, }); @@ -1195,8 +1209,8 @@ const mapDispatchToProps = (dispatch: Dispatch) => bindActionC }, dispatch); // NOTE: We don't need to pass generic type arguments to neither connect nor mapping functions because type inference will do all this work automatically. So there's really no reason to increase the noise ratio in your codebase! -export const SFCCounterConnectedVerbose = - connect(mapStateToProps, mapDispatchToProps)(SFCCounter); +export const FCCounterConnectedVerbose = + connect(mapStateToProps, mapDispatchToProps)(FCCounter); ``` [⇧ back to top](#table-of-contents) @@ -1430,7 +1444,7 @@ Using this solution you'll achieve better encapsulation for internal structure/n // 1. in `components/` folder create component file (`select.tsx`) with default export: // components/select.tsx -const Select: React.SFC = (props) => { +const Select: React.FC = (props) => { ... export default Select; @@ -1526,7 +1540,7 @@ Related `ts-lint` rule: https://palantir.github.io/tslint/rules/interface-over-t ### - how to best initialize class instance or static properties? > Prefered modern style is to use class Property Initializers ```tsx -class StatefulCounterWithInitialCount extends React.Component { +class ClassCounterWithInitialCount extends React.Component { // default props using Property Initializers static defaultProps: DefaultProps = { className: 'default-class', @@ -1546,7 +1560,7 @@ class StatefulCounterWithInitialCount extends React.Component { ### - how to best declare component handler functions? > Prefered modern style is to use Class Fields with arrow functions ```tsx -class StatefulCounter extends React.Component { +class ClassCounter extends React.Component { // handlers using Class Fields with arrow functions handleIncrement = () => { this.setState({ count: this.state.count + 1 }); diff --git a/README_SOURCE.md b/README_SOURCE.md index ab981a2..1db0fdc 100644 --- a/README_SOURCE.md +++ b/README_SOURCE.md @@ -46,8 +46,8 @@ This gives you the power to prioritize our work and support the project contribu - [Type Definitions & Complementary Libraries](#type-definitions--complementary-libraries) - [React Types Cheatsheet](#react-types-cheatsheet) 🌟 __NEW__ - [Component Typing Patterns](#component-typing-patterns) - - [Stateless Components - SFC](#stateless-components---sfc) - - [Stateful Components - Class](#stateful-components---class) 📝 __UPDATED__ + - [Function Components - FC](#function-components---fc) + - [Class Components ](#class-components) 📝 __UPDATED__ - [Generic Components](#generic-components) - [Render Props](#render-props) 🌟 __NEW__ - [Higher-Order Components](#higher-order-components) 📝 __UPDATED__ @@ -106,22 +106,22 @@ npm i -D @types/react @types/react-dom @types/react-redux # React Types Cheatsheet -#### `React.StatelessComponent

` or `React.SFC

` -Type representing stateless functional component +#### `React.FunctionComponent

` or `React.FC

` +Type representing a functional component ```tsx -const MyComponent: React.SFC = ... +const MyComponent: React.FC = ... ``` [⇧ back to top](#table-of-contents) #### `React.Component` -Type representing stateful class component +Type representing a class component ```tsx class MyComponent extends React.Component { ... ``` [⇧ back to top](#table-of-contents) #### `React.ComponentType

` -Type representing union type of (SFC | Component) +Type representing union type of (FC | Component) ```tsx const withState =

( WrappedComponent: React.ComponentType

, @@ -174,41 +174,41 @@ const handleChange = (ev: React.MouseEvent) => { ... } # Component Typing Patterns -## Stateless Components - SFC +## Function Components - FC -#### - stateless counter +#### - FC counter -::codeblock='playground/src/components/sfc-counter.tsx':: +::codeblock='playground/src/components/fc-counter.tsx':: -[⟩⟩⟩ demo](https://piotrwitek.github.io/react-redux-typescript-guide/#sfccounter) +[⟩⟩⟩ demo](https://piotrwitek.github.io/react-redux-typescript-guide/#fccounter) [⇧ back to top](#table-of-contents) #### - spread attributes [link](https://facebook.github.io/react/docs/jsx-in-depth.html#spread-attributes) -::codeblock='playground/src/components/sfc-spread-attributes.tsx':: +::codeblock='playground/src/components/fc-spread-attributes.tsx':: -[⟩⟩⟩ demo](https://piotrwitek.github.io/react-redux-typescript-guide/#sfcspreadattributes) +[⟩⟩⟩ demo](https://piotrwitek.github.io/react-redux-typescript-guide/#fcspreadattributes) [⇧ back to top](#table-of-contents) --- -## Stateful Components - Class +## Class Components -#### - stateful counter +#### - class counter -::codeblock='playground/src/components/stateful-counter.tsx':: +::codeblock='playground/src/components/class-counter.tsx':: -[⟩⟩⟩ demo](https://piotrwitek.github.io/react-redux-typescript-guide/#statefulcounter) +[⟩⟩⟩ demo](https://piotrwitek.github.io/react-redux-typescript-guide/#classcounter) [⇧ back to top](#table-of-contents) #### - with default props -::codeblock='playground/src/components/stateful-counter-with-default.tsx':: +::codeblock='playground/src/components/class-counter-with-default-props.tsx':: -[⟩⟩⟩ demo](https://piotrwitek.github.io/react-redux-typescript-guide/#statefulcounterwithdefault) +[⟩⟩⟩ demo](https://piotrwitek.github.io/react-redux-typescript-guide/#classcounterwithdefaultprops) [⇧ back to top](#table-of-contents) @@ -290,22 +290,22 @@ const mapDispatchToProps = (dispatch: Dispatch) => ({ #### - redux connected counter -::codeblock='playground/src/connected/sfc-counter-connected.tsx':: -::expander='playground/src/connected/sfc-counter-connected.usage.tsx':: +::codeblock='playground/src/connected/fc-counter-connected.tsx':: +::expander='playground/src/connected/fc-counter-connected.usage.tsx':: [⇧ back to top](#table-of-contents) #### - redux connected counter (verbose) -::codeblock='playground/src/connected/sfc-counter-connected-verbose.tsx':: -::expander='playground/src/connected/sfc-counter-connected-verbose.usage.tsx':: +::codeblock='playground/src/connected/fc-counter-connected-verbose.tsx':: +::expander='playground/src/connected/fc-counter-connected-verbose.usage.tsx':: [⇧ back to top](#table-of-contents) #### - with own props -::codeblock='playground/src/connected/sfc-counter-connected-extended.tsx':: -::expander='playground/src/connected/sfc-counter-connected-extended.usage.tsx':: +::codeblock='playground/src/connected/fc-counter-connected-extended.tsx':: +::expander='playground/src/connected/fc-counter-connected-extended.usage.tsx':: [⇧ back to top](#table-of-contents) @@ -468,7 +468,7 @@ When creating a store instance we don't need to provide any additional types. It ## Typing connect Below snippet can be find in the `playground/` folder, you can checkout the repo and follow all dependencies to understand the bigger picture. -`playground/src/connected/sfc-counter-connected-verbose.tsx` +`playground/src/connected/fc-counter-connected-verbose.tsx` ```tsx import Types from 'Types'; @@ -477,10 +477,10 @@ import { bindActionCreators, Dispatch } from 'redux'; import { connect } from 'react-redux'; import { countersActions } from '../features/counters'; -import { SFCCounter, SFCCounterProps } from '../components'; +import { FCCounter } from '../components'; // `state` parameter needs a type annotation to type-check the correct shape of a state object but also it'll be used by "type inference" to infer the type of returned props -const mapStateToProps = (state: Types.RootState, ownProps: SFCCounterProps) => ({ +const mapStateToProps = (state: Types.RootState, ownProps: FCCounterProps) => ({ count: state.counters.reduxCounter, }); @@ -492,8 +492,8 @@ const mapDispatchToProps = (dispatch: Dispatch) => bindActionC }, dispatch); // NOTE: We don't need to pass generic type arguments to neither connect nor mapping functions because type inference will do all this work automatically. So there's really no reason to increase the noise ratio in your codebase! -export const SFCCounterConnectedVerbose = - connect(mapStateToProps, mapDispatchToProps)(SFCCounter); +export const FCCounterConnectedVerbose = + connect(mapStateToProps, mapDispatchToProps)(FCCounter); ``` [⇧ back to top](#table-of-contents) @@ -572,7 +572,7 @@ Using this solution you'll achieve better encapsulation for internal structure/n // 1. in `components/` folder create component file (`select.tsx`) with default export: // components/select.tsx -const Select: React.SFC = (props) => { +const Select: React.FC = (props) => { ... export default Select; @@ -663,7 +663,7 @@ Related `ts-lint` rule: https://palantir.github.io/tslint/rules/interface-over-t ### - how to best initialize class instance or static properties? > Prefered modern style is to use class Property Initializers ```tsx -class StatefulCounterWithInitialCount extends React.Component { +class ClassCounterWithInitialCount extends React.Component { // default props using Property Initializers static defaultProps: DefaultProps = { className: 'default-class', @@ -683,7 +683,7 @@ class StatefulCounterWithInitialCount extends React.Component { ### - how to best declare component handler functions? > Prefered modern style is to use Class Fields with arrow functions ```tsx -class StatefulCounter extends React.Component { +class ClassCounter extends React.Component { // handlers using Class Fields with arrow functions handleIncrement = () => { this.setState({ count: this.state.count + 1 }); diff --git a/playground/src/components/stateful-counter-with-default.md b/playground/src/components/class-counter-with-default-props.md similarity index 50% rename from playground/src/components/stateful-counter-with-default.md rename to playground/src/components/class-counter-with-default-props.md index d6e4e24..010957d 100644 --- a/playground/src/components/stateful-counter-with-default.md +++ b/playground/src/components/class-counter-with-default-props.md @@ -1,10 +1,10 @@ Usage: -```jsx { "filePath": "./stateful-counter-with-default.usage.tsx" } +```jsx { "filePath": "./class-counter-with-default-props.usage.tsx" } ``` Usage Demo: ```jsx -const Demo = require('./stateful-counter-with-default.usage').default; +const Demo = require('./class-counter-with-default-props.usage').default; ``` diff --git a/playground/src/components/stateful-counter-with-default.tsx b/playground/src/components/class-counter-with-default-props.tsx similarity index 85% rename from playground/src/components/stateful-counter-with-default.tsx rename to playground/src/components/class-counter-with-default-props.tsx index 17fc115..851f330 100644 --- a/playground/src/components/stateful-counter-with-default.tsx +++ b/playground/src/components/class-counter-with-default-props.tsx @@ -1,15 +1,18 @@ import * as React from 'react'; -type Props = Readonly<{ +type Props = { label: string; initialCount: number; -}>; +}; -type State = Readonly<{ +type State = { count: number; -}>; +}; -export class StatefulCounterWithDefault extends React.Component { +export class ClassCounterWithDefaultProps extends React.Component< + Props, + State +> { static defaultProps = { initialCount: 0, }; diff --git a/playground/src/components/class-counter-with-default-props.usage.tsx b/playground/src/components/class-counter-with-default-props.usage.tsx new file mode 100644 index 0000000..2f6c7bf --- /dev/null +++ b/playground/src/components/class-counter-with-default-props.usage.tsx @@ -0,0 +1,7 @@ +import * as React from 'react'; + +import { ClassCounterWithDefaultProps } from '.'; + +export default () => ( + +); diff --git a/playground/src/components/class-counter.md b/playground/src/components/class-counter.md new file mode 100644 index 0000000..b6345e4 --- /dev/null +++ b/playground/src/components/class-counter.md @@ -0,0 +1,11 @@ +Usage: +```jsx { "filePath": "./class-counter.usage.tsx" } +``` + +Usage Demo: +```jsx +const Demo = require('./class-counter.usage').default; + +``` + +[⇦ back to guide](https://github.com/piotrwitek/react-redux-typescript-guide#--class-counter) diff --git a/playground/src/components/stateful-counter.tsx b/playground/src/components/class-counter.tsx similarity index 67% rename from playground/src/components/stateful-counter.tsx rename to playground/src/components/class-counter.tsx index e4629e9..2e547cc 100644 --- a/playground/src/components/stateful-counter.tsx +++ b/playground/src/components/class-counter.tsx @@ -1,21 +1,21 @@ import * as React from 'react'; -export interface StatefulCounterProps { +type Props = { label: string; -} +}; -interface State { - readonly count: number; -} +type State = { + count: number; +}; -export class StatefulCounter extends React.Component { +export class ClassCounter extends React.Component { readonly state: State = { count: 0, }; handleIncrement = () => { this.setState({ count: this.state.count + 1 }); - } + }; render() { const { handleIncrement } = this; @@ -24,7 +24,9 @@ export class StatefulCounter extends React.Component - {label}: {count} + + {label}: {count}{' '} + diff --git a/playground/src/components/class-counter.usage.tsx b/playground/src/components/class-counter.usage.tsx new file mode 100644 index 0000000..2734455 --- /dev/null +++ b/playground/src/components/class-counter.usage.tsx @@ -0,0 +1,5 @@ +import * as React from 'react'; + +import { ClassCounter } from '.'; + +export default () => ; diff --git a/playground/src/components/error-message.tsx b/playground/src/components/error-message.tsx index a3929ac..e91981e 100644 --- a/playground/src/components/error-message.tsx +++ b/playground/src/components/error-message.tsx @@ -1,6 +1,6 @@ import * as React from 'react'; -export const ErrorMessage: React.SFC<{ onReset: () => void }> = ({ +export const ErrorMessage: React.FC<{ onReset: () => void }> = ({ onReset, }) => { return ( diff --git a/playground/src/components/fc-counter.md b/playground/src/components/fc-counter.md new file mode 100644 index 0000000..b839819 --- /dev/null +++ b/playground/src/components/fc-counter.md @@ -0,0 +1,11 @@ +Usage: +```jsx { "filePath": "./fc-counter.usage.tsx" } +``` + +Usage Demo: +```jsx +const Demo = require('./fc-counter.usage').default; + +``` + +[⇦ back to guide](https://github.com/piotrwitek/react-redux-typescript-guide#--fc-counter) diff --git a/playground/src/components/sfc-counter.tsx b/playground/src/components/fc-counter.tsx similarity index 58% rename from playground/src/components/sfc-counter.tsx rename to playground/src/components/fc-counter.tsx index a75b0a4..23f0cec 100644 --- a/playground/src/components/sfc-counter.tsx +++ b/playground/src/components/fc-counter.tsx @@ -1,19 +1,23 @@ import * as React from 'react'; -export interface SFCCounterProps { +type Props = { label: string; count: number; onIncrement: () => any; -} +}; -export const SFCCounter: React.SFC = (props) => { +export const FCCounter: React.FC = props => { const { label, count, onIncrement } = props; - const handleIncrement = () => { onIncrement(); }; + const handleIncrement = () => { + onIncrement(); + }; return (

- {label}: {count} + + {label}: {count}{' '} + diff --git a/playground/src/components/sfc-counter.usage.tsx b/playground/src/components/fc-counter.usage.tsx similarity index 77% rename from playground/src/components/sfc-counter.usage.tsx rename to playground/src/components/fc-counter.usage.tsx index 4a3d532..4aff6c0 100644 --- a/playground/src/components/sfc-counter.usage.tsx +++ b/playground/src/components/fc-counter.usage.tsx @@ -1,14 +1,14 @@ import * as React from 'react'; -import { SFCCounter } from '../components'; +import { FCCounter } from '.'; export default class extends React.Component<{}, { count: number }> { state = { count: 0 }; render() { return ( - { this.setState({ count: this.state.count + 1 }); diff --git a/playground/src/components/sfc-spread-attributes.md b/playground/src/components/fc-spread-attributes.md similarity index 55% rename from playground/src/components/sfc-spread-attributes.md rename to playground/src/components/fc-spread-attributes.md index 9dd1635..93a52dc 100644 --- a/playground/src/components/sfc-spread-attributes.md +++ b/playground/src/components/fc-spread-attributes.md @@ -1,10 +1,10 @@ Usage: -```jsx { "filePath": "./sfc-spread-attributes.usage.tsx" } +```jsx { "filePath": "./fc-spread-attributes.usage.tsx" } ``` Usage Demo: ```jsx -const Demo = require('./sfc-spread-attributes.usage').default; +const Demo = require('./fc-spread-attributes.usage').default; ``` diff --git a/playground/src/components/fc-spread-attributes.tsx b/playground/src/components/fc-spread-attributes.tsx new file mode 100644 index 0000000..8aa90b1 --- /dev/null +++ b/playground/src/components/fc-spread-attributes.tsx @@ -0,0 +1,12 @@ +import * as React from 'react'; + +type Props = { + className?: string; + style?: React.CSSProperties; +}; + +export const FCSpreadAttributes: React.FC = props => { + const { children, ...restProps } = props; + + return
{children}
; +}; diff --git a/playground/src/components/sfc-spread-attributes.usage.tsx b/playground/src/components/fc-spread-attributes.usage.tsx similarity index 64% rename from playground/src/components/sfc-spread-attributes.usage.tsx rename to playground/src/components/fc-spread-attributes.usage.tsx index b880145..92c1fde 100644 --- a/playground/src/components/sfc-spread-attributes.usage.tsx +++ b/playground/src/components/fc-spread-attributes.usage.tsx @@ -1,12 +1,12 @@ import * as React from 'react'; -import { SFCSpreadAttributes } from '../components'; +import { FCSpreadAttributes } from '.'; export default () => ( - {`I'll spread every property you give me!`} - + ); diff --git a/playground/src/components/index.ts b/playground/src/components/index.ts index 1930915..ac8706e 100644 --- a/playground/src/components/index.ts +++ b/playground/src/components/index.ts @@ -1,8 +1,8 @@ export * from './error-message'; export * from './generic-list'; -export * from './sfc-counter'; -export * from './sfc-spread-attributes'; -export * from './stateful-counter'; -export * from './stateful-counter-with-default'; +export * from './fc-counter'; +export * from './fc-spread-attributes'; +export * from './class-counter'; +export * from './class-counter-with-default-props'; export * from './name-provider'; export * from './mouse-provider'; diff --git a/playground/src/components/sfc-counter.md b/playground/src/components/sfc-counter.md deleted file mode 100644 index 05fa977..0000000 --- a/playground/src/components/sfc-counter.md +++ /dev/null @@ -1,11 +0,0 @@ -Usage: -```jsx { "filePath": "./sfc-counter.usage.tsx" } -``` - -Usage Demo: -```jsx -const Demo = require('./sfc-counter.usage').default; - -``` - -[⇦ back to guide](https://github.com/piotrwitek/react-redux-typescript-guide#--stateless-counter) diff --git a/playground/src/components/sfc-spread-attributes.tsx b/playground/src/components/sfc-spread-attributes.tsx deleted file mode 100644 index 4660a07..0000000 --- a/playground/src/components/sfc-spread-attributes.tsx +++ /dev/null @@ -1,16 +0,0 @@ -import * as React from 'react'; - -export interface SFCSpreadAttributesProps { - className?: string; - style?: React.CSSProperties; -} - -export const SFCSpreadAttributes: React.SFC = (props) => { - const { children, ...restProps } = props; - - return ( -
- {children} -
- ); -}; diff --git a/playground/src/components/stateful-counter-with-default.usage.tsx b/playground/src/components/stateful-counter-with-default.usage.tsx deleted file mode 100644 index 8ad44d5..0000000 --- a/playground/src/components/stateful-counter-with-default.usage.tsx +++ /dev/null @@ -1,9 +0,0 @@ -import * as React from 'react'; - -import { StatefulCounterWithDefault } from '../components'; - -export default () => ( - -); diff --git a/playground/src/components/stateful-counter.md b/playground/src/components/stateful-counter.md deleted file mode 100644 index 3811ed1..0000000 --- a/playground/src/components/stateful-counter.md +++ /dev/null @@ -1,11 +0,0 @@ -Usage: -```jsx { "filePath": "./stateful-counter.usage.tsx" } -``` - -Usage Demo: -```jsx -const Demo = require('./stateful-counter.usage').default; - -``` - -[⇦ back to guide](https://github.com/piotrwitek/react-redux-typescript-guide#--stateful-counter) diff --git a/playground/src/components/stateful-counter.usage.tsx b/playground/src/components/stateful-counter.usage.tsx deleted file mode 100644 index 7fc4b9a..0000000 --- a/playground/src/components/stateful-counter.usage.tsx +++ /dev/null @@ -1,9 +0,0 @@ -import * as React from 'react'; - -import { StatefulCounter } from '../components'; - -export default () => ( - -); diff --git a/playground/src/connected/fc-counter-connected-extended.tsx b/playground/src/connected/fc-counter-connected-extended.tsx new file mode 100644 index 0000000..e84c9a7 --- /dev/null +++ b/playground/src/connected/fc-counter-connected-extended.tsx @@ -0,0 +1,21 @@ +import Types from 'Types'; +import { connect } from 'react-redux'; + +import { countersActions, countersSelectors } from '../features/counters'; +import { FCCounter } from '../components'; + +type OwnProps = { + initialCount: number; +}; + +const mapStateToProps = (state: Types.RootState, ownProps: OwnProps) => ({ + count: + countersSelectors.getReduxCounter(state.counters) + ownProps.initialCount, +}); + +export const FCCounterConnectedExtended = connect( + mapStateToProps, + { + onIncrement: countersActions.increment, + } +)(FCCounter); diff --git a/playground/src/connected/fc-counter-connected-extended.usage.tsx b/playground/src/connected/fc-counter-connected-extended.usage.tsx new file mode 100644 index 0000000..da025d3 --- /dev/null +++ b/playground/src/connected/fc-counter-connected-extended.usage.tsx @@ -0,0 +1,10 @@ +import * as React from 'react'; + +import { FCCounterConnectedExtended } from '.'; + +export default () => ( + +); diff --git a/playground/src/connected/sfc-counter-connected-verbose.tsx b/playground/src/connected/fc-counter-connected-verbose.tsx similarity index 57% rename from playground/src/connected/sfc-counter-connected-verbose.tsx rename to playground/src/connected/fc-counter-connected-verbose.tsx index dfc9b55..cb952ae 100644 --- a/playground/src/connected/sfc-counter-connected-verbose.tsx +++ b/playground/src/connected/fc-counter-connected-verbose.tsx @@ -3,15 +3,21 @@ import { bindActionCreators, Dispatch } from 'redux'; import { connect } from 'react-redux'; import { countersActions } from '../features/counters'; -import { SFCCounter } from '../components'; +import { FCCounter } from '../components'; const mapStateToProps = (state: Types.RootState) => ({ count: state.counters.reduxCounter, }); -const mapDispatchToProps = (dispatch: Dispatch) => bindActionCreators({ - onIncrement: countersActions.increment, -}, dispatch); +const mapDispatchToProps = (dispatch: Dispatch) => + bindActionCreators( + { + onIncrement: countersActions.increment, + }, + dispatch + ); -export const SFCCounterConnectedVerbose = - connect(mapStateToProps, mapDispatchToProps)(SFCCounter); +export const FCCounterConnectedVerbose = connect( + mapStateToProps, + mapDispatchToProps +)(FCCounter); diff --git a/playground/src/connected/fc-counter-connected-verbose.usage.tsx b/playground/src/connected/fc-counter-connected-verbose.usage.tsx new file mode 100644 index 0000000..6e47ddf --- /dev/null +++ b/playground/src/connected/fc-counter-connected-verbose.usage.tsx @@ -0,0 +1,7 @@ +import * as React from 'react'; + +import { FCCounterConnectedVerbose } from '.'; + +export default () => ( + +); diff --git a/playground/src/connected/sfc-counter-connected.tsx b/playground/src/connected/fc-counter-connected.tsx similarity index 60% rename from playground/src/connected/sfc-counter-connected.tsx rename to playground/src/connected/fc-counter-connected.tsx index 3863ab4..82568e3 100644 --- a/playground/src/connected/sfc-counter-connected.tsx +++ b/playground/src/connected/fc-counter-connected.tsx @@ -2,12 +2,15 @@ import Types from 'Types'; import { connect } from 'react-redux'; import { countersActions, countersSelectors } from '../features/counters'; -import { SFCCounter } from '../components'; +import { FCCounter } from '../components'; const mapStateToProps = (state: Types.RootState) => ({ count: countersSelectors.getReduxCounter(state.counters), }); -export const SFCCounterConnected = connect(mapStateToProps, { - onIncrement: countersActions.increment, -})(SFCCounter); +export const FCCounterConnected = connect( + mapStateToProps, + { + onIncrement: countersActions.increment, + } +)(FCCounter); diff --git a/playground/src/connected/fc-counter-connected.usage.tsx b/playground/src/connected/fc-counter-connected.usage.tsx new file mode 100644 index 0000000..7cd6da6 --- /dev/null +++ b/playground/src/connected/fc-counter-connected.usage.tsx @@ -0,0 +1,5 @@ +import * as React from 'react'; + +import { FCCounterConnected } from '.'; + +export default () => ; diff --git a/playground/src/connected/index.ts b/playground/src/connected/index.ts index 404261b..33625dc 100644 --- a/playground/src/connected/index.ts +++ b/playground/src/connected/index.ts @@ -1,3 +1,3 @@ -export * from './sfc-counter-connected-extended'; -export * from './sfc-counter-connected-verbose'; -export * from './sfc-counter-connected'; +export * from './fc-counter-connected-extended'; +export * from './fc-counter-connected-verbose'; +export * from './fc-counter-connected'; diff --git a/playground/src/connected/sfc-counter-connected-extended.tsx b/playground/src/connected/sfc-counter-connected-extended.tsx deleted file mode 100644 index 84e01f1..0000000 --- a/playground/src/connected/sfc-counter-connected-extended.tsx +++ /dev/null @@ -1,17 +0,0 @@ -import Types from 'Types'; -import { connect } from 'react-redux'; - -import { countersActions, countersSelectors } from '../features/counters'; -import { SFCCounter } from '../components'; - -export interface SFCCounterConnectedExtendedProps { - initialCount: number; -} - -const mapStateToProps = (state: Types.RootState, ownProps: SFCCounterConnectedExtendedProps) => ({ - count: countersSelectors.getReduxCounter(state.counters) + ownProps.initialCount, -}); - -export const SFCCounterConnectedExtended = connect(mapStateToProps, { - onIncrement: countersActions.increment, -})(SFCCounter); diff --git a/playground/src/connected/sfc-counter-connected-extended.usage.tsx b/playground/src/connected/sfc-counter-connected-extended.usage.tsx deleted file mode 100644 index 7321ffc..0000000 --- a/playground/src/connected/sfc-counter-connected-extended.usage.tsx +++ /dev/null @@ -1,5 +0,0 @@ -import * as React from 'react'; - -import { SFCCounterConnectedExtended } from '../connected'; - -export default () => ; diff --git a/playground/src/connected/sfc-counter-connected-verbose.usage.tsx b/playground/src/connected/sfc-counter-connected-verbose.usage.tsx deleted file mode 100644 index 0d48a37..0000000 --- a/playground/src/connected/sfc-counter-connected-verbose.usage.tsx +++ /dev/null @@ -1,9 +0,0 @@ -import * as React from 'react'; - -import { SFCCounterConnectedVerbose } from '../connected'; - -export default () => ( - -); diff --git a/playground/src/connected/sfc-counter-connected.usage.tsx b/playground/src/connected/sfc-counter-connected.usage.tsx deleted file mode 100644 index c6baf27..0000000 --- a/playground/src/connected/sfc-counter-connected.usage.tsx +++ /dev/null @@ -1,9 +0,0 @@ -import * as React from 'react'; - -import { SFCCounterConnected } from '../connected'; - -export default () => ( - -); diff --git a/playground/src/hoc/with-state.usage.tsx b/playground/src/hoc/with-state.usage.tsx index 12c76c5..d27c99c 100644 --- a/playground/src/hoc/with-state.usage.tsx +++ b/playground/src/hoc/with-state.usage.tsx @@ -1,11 +1,8 @@ import * as React from 'react'; import { withState } from '../hoc'; -import { SFCCounter } from '../components'; +import { FCCounter } from '../components'; -const SFCCounterWithState = - withState(SFCCounter); +const FCCounterWithState = withState(FCCounter); -export default () => ( - -); +export default () => ; diff --git a/playground/src/pages/home.tsx b/playground/src/pages/home.tsx index d4a330a..0cb0293 100644 --- a/playground/src/pages/home.tsx +++ b/playground/src/pages/home.tsx @@ -1,18 +1,18 @@ import * as React from 'react'; -import SFCCounter from '../components/sfc-counter.usage'; -import SFCSpreadAttributes from '../components/sfc-spread-attributes.usage'; -import StatefulCounter from '../components/stateful-counter.usage'; -import StatefulCounterWithInitialCount from '../components/stateful-counter-with-default.usage'; +import FCCounter from '../components/fc-counter.usage'; +import FCSpreadAttributes from '../components/fc-spread-attributes.usage'; +import ClassCounter from '../components/class-counter.usage'; +import ClassCounterWithDefaultProps from '../components/class-counter-with-default-props.usage'; import UserListUsage from '../components/generic-list.usage'; export const Home = () => { return (
- - - - + + + +
); diff --git a/playground/styleguide.config.js b/playground/styleguide.config.js index a58c3bb..f7ed140 100644 --- a/playground/styleguide.config.js +++ b/playground/styleguide.config.js @@ -13,34 +13,32 @@ module.exports = { sections: [ { name: 'Introduction', - content: './docs/intro.md' + content: './docs/intro.md', }, { - name: 'Stateless Components - SFC', - components: () => ([ - './src/components/sfc-counter.tsx', - './src/components/sfc-spread-attributes.tsx', - ]), + name: 'Function Components', + components: () => [ + './src/components/fc-counter.tsx', + './src/components/fc-spread-attributes.tsx', + ], }, { - name: 'Stateful Components - Class', - components: () => ([ - './src/components/stateful-counter.tsx', - './src/components/stateful-counter-with-default.tsx', - ]), + name: 'Class Components', + components: () => [ + './src/components/class-counter.tsx', + './src/components/class-counter-with-default-props.tsx', + ], }, { name: 'Generic Components', - components: () => ([ - './src/components/generic-list.tsx', - ]), + components: () => ['./src/components/generic-list.tsx'], }, { name: 'Render Props', - components: () => ([ + components: () => [ './src/components/name-provider.tsx', './src/components/mouse-provider.tsx', - ]), + ], }, ], theme: { @@ -48,18 +46,20 @@ module.exports = { }, propsParser: require('react-docgen-typescript').parse, webpackConfig: webpackConfig, - updateExample: function (props, exampleFilePath) { + updateExample: function(props, exampleFilePath) { if (typeof props.settings.filePath === 'string') { - const { settings: { filePath } } = props; + const { + settings: { filePath }, + } = props; delete props.settings.filePath; props.content = fs.readFileSync( path.resolve(exampleFilePath, '..', filePath), { encoding: 'utf-8' } ); - props.settings.static = true + props.settings.static = true; } - return props - } -} + return props; + }, +};