`
+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 =
@@ -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
`
+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 (
-