Skip to content

Latest commit

 

History

History
204 lines (134 loc) · 6.52 KB

File metadata and controls

204 lines (134 loc) · 6.52 KB

React Types Cheatsheet

React.StatelessComponent<P> or React.SFC<P>

Type representing stateless functional component

const MyComponent: React.SFC<MyComponentProps> = ...

⇧ back to top

React.Component<P, S>

Type representing stateful class component

class MyComponent extends React.Component<MyComponentProps, State> { ...

⇧ back to top

React.ComponentType<P>

Type representing union type of (SFC | Component)

const withState = <P extends WrappedComponentProps>(
  WrappedComponent: React.ComponentType<P>,
) => { ...

⇧ back to top

React.ReactElement<P> or JSX.Element

Type representing a concept of React Element - representation of a native DOM component (e.g. <div />), or a user-defined composite component (e.g. <MyComponent />)

const elementOnly: React.ReactElement = <div /> || <MyComponent />;

⇧ back to top

React.ReactNode

Type representing any possible type of React node (basically ReactElement (including Fragments and Portals) + primitive JS types)

const elementOrPrimitive: React.ReactNode = 'string' || 0 || false || null || undefined || <div /> || <MyComponent />;
const Component = ({ children: React.ReactNode }) => ...

⇧ back to top

React.CSSProperties

Type representing style object in JSX (usefull for css-in-js styles)

const styles: React.CSSProperties = { flexDirection: 'row', ...
const element = <div style={styles} ...

⇧ back to top

React.ReactEventHandler<E>

Type representing generic event handler

const handleChange: React.ReactEventHandler<HTMLInputElement> = (ev) => { ... } 

<input onChange={handleChange} ... />

⇧ back to top

React.MouseEvent<E> | React.KeyboardEvent<E> | React.TouchEvent<E> etc...

Type representing more specific event handler

const handleChange = (ev: React.MouseEvent<HTMLDivElement>) => { ... }

<div onMouseMove={handleChange} ... />

⇧ back to top


Component Typing Patterns

Stateless Components - SFC

- stateless counter

::example='../../playground/src/components/sfc-counter.tsx'::

⟩⟩⟩ demo

⇧ back to top

- spread attributes link

::example='../../playground/src/components/sfc-spread-attributes.tsx'::

⟩⟩⟩ demo

⇧ back to top


Stateful Components - Class

- stateful counter

::example='../../playground/src/components/stateful-counter.tsx'::

⟩⟩⟩ demo

⇧ back to top

- with default props

::example='../../playground/src/components/stateful-counter-with-default.tsx'::

⟩⟩⟩ demo

⇧ back to top


Generic Components

  • easily create typed component variations and reuse common logic
  • common use case is a generic list components

- generic list

::example='../../playground/src/components/generic-list.tsx'::

⟩⟩⟩ demo

⇧ back to top


Render Props

https://reactjs.org/docs/render-props.html

- name provider

simple component using children as a render prop

::example='../../playground/src/components/name-provider.tsx'::

⟩⟩⟩ demo

⇧ back to top

- mouse provider

Mouse component found in Render Props React Docs

::example='../../playground/src/components/mouse-provider.tsx'::

⟩⟩⟩ demo

⇧ back to top


Higher-Order Components

https://reactjs.org/docs/higher-order-components.html

- withState

Adds state to a stateless counter

::example='../../playground/src/hoc/with-state.tsx':: ::usage='../../playground/src/hoc/with-state.usage.tsx'::

⇧ back to top

- withErrorBoundary

Adds error handling using componentDidCatch to any component

::example='../../playground/src/hoc/with-error-boundary.tsx':: ::usage='../../playground/src/hoc/with-error-boundary.usage.tsx'::

⇧ back to top


Redux Connected Components

Caveat with bindActionCreators

If you try to use connect or bindActionCreators explicitly and want to type your component callback props as () => void this will raise compiler errors. It happens because bindActionCreators typings will not map the return type of action creators to void, due to a current TypeScript limitations.

A decent alternative I can recommend is to use () => any type, it will work just fine in all possible scenarios and should not cause any typing problems whatsoever. All the code examples in the Guide with connect are also using this pattern.

If there is any progress or fix in regard to the above caveat I'll update the guide and make an announcement on my twitter/medium (There are a few existing proposals already).

There is alternative way to retain type soundness but it requires an explicit wrapping with dispatch and will be very tedious for the long run. See example below:

const mapDispatchToProps = (dispatch: Dispatch<ActionType>) => ({
  onIncrement: () => dispatch(actions.increment()),
});

- redux connected counter

::example='../../playground/src/connected/sfc-counter-connected.tsx':: ::usage='../../playground/src/connected/sfc-counter-connected.usage.tsx'::

⇧ back to top

- redux connected counter (verbose)

::example='../../playground/src/connected/sfc-counter-connected-verbose.tsx':: ::usage='../../playground/src/connected/sfc-counter-connected-verbose.usage.tsx'::

⇧ back to top

- with own props

::example='../../playground/src/connected/sfc-counter-connected-extended.tsx':: ::usage='../../playground/src/connected/sfc-counter-connected-extended.usage.tsx'::

⇧ back to top