React-Snippets

Eine Snippet-Sammlung für React.

Auf der Seite React-Grundlagen habe ich Einsteiger-Infos zu React zusammengestellt.

Links:

Performance Debugging:

Bibliothen:

Tools:

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:

Wo this.setState verboten ist:

TODO

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