Eine einzelne Box mit D'n'D verschieben
bei jeder Bewegung der Maus werden alle Boxen neu gerendert
Nicht direkt im DOM, sondern in einer leichtgewichtigen Datenstruktur (Virtual DOM)
Änderungen im echten DOM werden aus Änderungen im Virtual DOM errechnet
shouldComponentUpdate ist eine Lifecycle-Methode einer Komponente die diese Prozedur abkürzen kann
das alte Modell kann mit dem neuen verglichen werden
Das reduziert das Neu-Rendering auf genau die notwendigen Elemente
Macht nur Sinn, wenn der Check auf Modell-Änderung sehr billig ist, typischerweise ===
class Box extends React.Component {
shouldComponentUpdate(nextProps) {
// simple check: every change to a box creates a new object
const changed = this.props.box !== nextProps.box;
return changed;
}
render() {
const {box} = this.props;
return <rect data-id={box.id} x={box.x} y={box.y}
width="10" height="10"
stroke="black" fill="transparent" strokeWidth="1"/>;
}
}
updateBox(id, x, y) {
const {boxes} = this.state;
const modifiedBox = {
id,
x,
y
};
// https://developer.mozilla.org/en-US/docs/Web/JavaScript/
// Reference/Global_Objects/Array/slice
const boxesBefore = boxes.slice(0, id);
const boxesAfter = boxes.slice(id + 1);
const modifiedBoxes = [...boxesBefore, modifiedBox, ...boxesAfter];
this.setState({
boxes: modifiedBoxes
});
}
Immutable persistent data collections for Javascript which increase efficiency and simplicity.
http://facebook.github.io/immutable-js/
import {List} from 'immutable';
this.state = {
boxes: List(boxes)
};
updateBox(id, x, y) {
const {boxes} = this.state;
const modifiedBox = {
id,
x,
y
};
const modifiedBoxes = boxes.set(id, modifiedBox);
this.setState({
boxes: modifiedBoxes
});
}
Komplexe Anwendung mit vielen interaktiven Abhängigkeit
Redux
Allerdings: Lernkurve steil, gerade am Anfang wirklich viel Code
Redux ist für kleinere Anwendungen meistens Overkill
MobX erlaubt einen sehr einfachen Einstieg
Es gibt eine große Anzahl von sehr praktischen JavaScript-Bibliotheken
Viele davon sind aber nicht als React-Komponenten entwickelt worden
Beispiele
jQuery und jQuery Plugins wie z.B. Bootstrap
d3 für interaktive SVGs und Chart Bibliotheken wie nvd3
nvd3 Pie Chart mit d3
class Chart extends React.Component {
render() {
// we render an empty svg and
// remember the reference to the DOM node
return <svg ref={c => this._chart = c}></svg>
}
// called directly after first render
componentDidMount() {
// once rendered by react we create the nvd3 chart
const chart = createNvd3Chart(this._chart, this.props.data);
// we delegate the label of clicked segment
// back to parent component
chart.pie.dispatch.on("elementClick",
e => this.props.onSegmentSelected(e.data.label));
}
// ...
}
class Chart extends React.Component {
// ...
// if it returns false, component will not be rendered
shouldComponentUpdate() {
// once rendered react never renders again
return false;
}
// called when properties update
componentWillReceiveProps(nextProps) {
const {data} = nextProps;
// we still get updates of properties making it reactive
updateNvd3Chart(this._chart, data);
}
// called just before destroying component
componentWillUnmount() {
this._d3selection.remove();
}
}
Jeder kann ein Sponsor werden
Minifizieren, Optimieren und alle React-Warnungen herauskompilieren:
webpack --optimize-minimize --define process.env.NODE_ENV=\"'production'\"
Oder als Kurzform:
webpack -p
https://webpack.js.org/guides/production-build/
SourceMaps in eigene Datei schreiben (Webpack Konfiguration):
devtool: 'source-map'
-p
aufgerufen.babelrc
:
"presets": [["es2015", { "modules": false }]
https://webpack.js.org/guides/code-splitting-async/
class AsyncComponent extends React.Component {
componentDidMount() {
import(/* webpackChunkName: "component" */ './Component')
.then(ComponentModule => {
this.Component = ComponentModule.default;
this.forceUpdate();
});
}
render() {
return this.Component ?
<this.Component /> : <span>Loading...</span>;
}
}
Fertige Lösung: React Loadable
Allgemeine Bibliotheken können von CDNs geladen werden und landen nicht im Webpack build
Vorteil: Caching (sowohl im Browser als auch in mittleren Schichten), mehrere parallele Requests
externals: {
"react": "React",
"react-dom": "ReactDOM",
"prop-types": "PropTypes",
"d3": "d3",
"nvd3": "nv"
}