React-Snippets
Eine Snippet-Sammlung für React.
Auf der Seite React-Grundlagen habe ich Einsteiger-Infos zu React zusammengestellt.
Links:
- Thinking in react - Wie baue ich aus einem UI-Konzept eine React-App?
- react für SVG TODO
- Storybook - React-Komponenten isoliert testen
- Blog-Artikel: React on ES6+
- Blog-Artikel Handling state changes über das asynchrone Verhalten von
setState
- Blog-Artikel Understanding React component life-cycle - über den neuen React Life-Cycle
- TODO Error Boundaries in React 16
Performance Debugging:
- Blog-Artikel: React Performance Debugging
- Blog-Artikel: Performance optimisations for React applications
- Why did you update - Tool, das in der Konsole potentiell unnötige UI-Updates ausgibt.
Bibliothen:
- preact - Eine 3kB React-Alternative mit gleicher API (Siehe auch preact auf GitHub)
- glamorous - Eine Bibliothek, um Styles direkt im
jsx
-Code zu definieren- Einführung siehe Blog-Artikel Introducing glamorous
- Setzt auf glamor auf
- react-datasheet - Excel-artiges Grid mit Support für Formeln und eingebetteten Komponenten
- Blog-Artikel: 11 React Component Libraries You Should Know In 2018.
Mit Libs wie React Material-UI, React-Bootstrap, ...
Tools:
- svgr - Konvertiert SVG-Dateien in React-Komponenten. Das SVG-Markup wird dabei mit svgo vereinfacht, indem z.B. unnötige Gruppen und Attribute entfernt werden.
Klassenstruktur
Nach John Cobb.
Minimal:
import React from 'react'
import classnames from 'classnames'
interface Props {
className?: any
}
export default class MyComponent extends React.Component<Props> {
render() {
const props = this.props
return (
<div className={classnames(props.className, 'MyComponent')}>
</div>
)
}
}
Full blown:
import React from 'react'
import { connect } from 'react-redux'
import classnames from 'classnames'
import { AppState } from 'app/state/reducers'
import './MyComponent.less'
interface OwnProps {
className?: any
}
interface StateProps {
}
interface DispatchProps {
}
interface Props extends OwnProps, StateProps, DispatchProps {}
interface State {
}
export class MyComponent extends React.Component<Props, State> {
static defaultProps: Partial<Props> = {
...
}
// Initialisierung
constructor(props: Props) {
super(props)
this.state = {}
}
// Lifecycle events (Reihenfolge wie Ausführung)
static getDerivedStateFromProps(nextProps: Props, prevState: State): Partial<State> | null {
return null
}
shouldComponentUpdate(nextProps: Props, nextState: Props, nextContext: any) { return true }
getSnapshotBeforeUpdate(prevProps: Props, prevState: State): any { return { my: 'snapshot' } }
componentDidMount() {}
componentDidUpdate(prevProps: Props, prevState: State, snapshot: any) {}
componentWillUnmount() {}
// Eigene Methoden
_parseData() {}
_onSelect() {}
// render-Methode immer am Ende (so findet man sie schnell)
render() {
const props = this.props
return (
<div className={classnames(props.className, 'MyComponent')}>
</div>
)
}
}
const Connected = connect<StateProps, DispatchProps, OwnProps, AppState>(
(state: AppState, props: OwnProps) => {
return {
...props,
...
}
},
dispatch => ({
onBla() { dispatch(bla()) }
})
)(MyComponent)
export default Connected
setState
Mögliche Aufrufe:
this.setState((prevState, props) => {
return {counter: prevState.counter + props.step}
})
this.setState({ active: false })
Wo this.setState
erlaubt ist:
componentWillMount
componentWillReceiveProps
Wo this.setState
verboten ist:
componentWillUpdate
render
TODO
componentDidMount
componentDidUpdate
Optionale Elemente in JSX
Quelle: Blog-Artikel
let optionalElement
if (this.props.condition) {
optionalElement = (<div> ... </div>)
}
return (
<div>
...
{optionalElement}
...
</div>
)
Oder inline:
return (
<div>
...
{this.props.condition &&
<div> ... </div>
}
...
</div>
)
Listen iterieren in JSX
Quelle: Blog-Artikel
<div>
{this.props.list.map((data, i) =>
<Component key={i} data={data} />
)}
</div>
Kind-Elemente
Quelle: Blog-Artikel
Kind-Elemente werden von JSX an props.children
übergeben:
import { render } from 'react-dom'
const MyDiv = (props) => {
return (<div>{props.children}</div>)
}
render(
<MyDiv>
<span>Hello</span>
<span>World</span>
</MyDiv>,
rootElement
)
Bitte beachten: Will man etwas anderes tun, als die Kinder 1:1 durchreichen (z.B. verändern oder voneinander trennen), dann sollte man nicht direkt auf props.children
arbeiten, sondern die Utilitys React.Children verwenden. Siehe Beispiel aus Blog-Artikel.
Referenzen
Quelle: React-Doku "Refs to Components"
import ReactDOM from 'react-dom'
...
<input ref="myInput" />
...
const input = this.refs.myInput;
const inputValue = input.value;
ReactDOM.findDOMNode(input).focus();
Dynamische CSS-Klassen
classnames installieren:
npm install --save classnames
import React, { Component } from 'react'
import PropTypes from 'prop-types'
import classNames from 'classnames'
export default class MyComponent extends Component {
static propTypes = {
className: PropTypes.string
}
render() {
const className = classNames(
'MyView',
this.props.className, // May be null
{ 'isOpen': this.state.isOpen }
)
return (
<div className={className} />
)
}
}
Inner HTML
<div dangerouslySetInnerHTML={{__html: '<b>Hallo</b> there'}} />
Form-Validierung
- Blog-Artikel - Basis-Infos zu Forms in React
- formsy-react - Lib mit Basis-Logik für Validierung. Siehe Beispiel
- formsy-react-components - Form-Elemente für Bootstrap-Styling. Siehe Playground
- formsy-material-ui - Form-Elemente für Material UI