Skip to content

Commit 96dd39e

Browse files
committed
Merge branch 'rmdm-redux-combiner'
2 parents c8b45c7 + 36eb485 commit 96dd39e

File tree

9 files changed

+485
-0
lines changed

9 files changed

+485
-0
lines changed
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
{
2+
presets: [ "es2015", "react"],
3+
plugins: [ ]
4+
}
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
<!DOCTYPE html>
2+
<html lang="en">
3+
<head>
4+
<meta charset="utf-8" />
5+
<title>React + Redux-Combiner</title>
6+
<link href="/css/currentStyle.css" rel="stylesheet"/>
7+
</head>
8+
<body>
9+
<div id='main'></div>
10+
<script src='dist/main.js'></script>
11+
</body>
12+
</html>
Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
{
2+
"name": "js-framework-benchmark-react",
3+
"version": "1.0.0",
4+
"description": "React+redux-combiner demo",
5+
"main": "index.js",
6+
"scripts": {
7+
"build-dev": "webpack -w -d",
8+
"build-prod": "webpack -p"
9+
},
10+
"keywords": [
11+
"react",
12+
"redux",
13+
"redux-combiner"
14+
],
15+
"author": "Stefan Krause",
16+
"license": "Apache-2.0",
17+
"homepage": "https://github.com/krausest/js-framework-benchmark",
18+
"repository": {
19+
"type": "git",
20+
"url": "https://github.com/krausest/js-framework-benchmark.git"
21+
},
22+
"devDependencies": {
23+
"babel-core": "6.26.0",
24+
"babel-loader": "7.1.2",
25+
"babel-preset-es2015": "6.24.1",
26+
"babel-preset-react": "6.24.1",
27+
"jsx-loader": "0.13.2",
28+
"webpack": "3.8.1"
29+
},
30+
"dependencies": {
31+
"react": "16.1.0",
32+
"react-dom": "16.1.0",
33+
"react-redux": "5.0.6",
34+
"redux": "3.7.2",
35+
"redux-combiner": "0.4.1"
36+
}
37+
}
Lines changed: 202 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,202 @@
1+
'use strict';
2+
3+
import React from 'react'
4+
import {connect} from 'react-redux';
5+
import {
6+
buildData,
7+
remove,
8+
run,
9+
add,
10+
update,
11+
select,
12+
runLots,
13+
clear,
14+
swapRows
15+
} from './store';
16+
17+
18+
var startTime;
19+
var lastMeasure;
20+
var startMeasure = function(name) {
21+
performance.mark('mark_start_'+name);
22+
startTime = performance.now();
23+
lastMeasure = name;
24+
}
25+
var stopMeasure = function() {
26+
var last = lastMeasure;
27+
if (lastMeasure) {
28+
window.setTimeout(function () {
29+
lastMeasure = null;
30+
var stop = performance.now();
31+
var duration = 0;
32+
performance.mark('mark_end_' + last);
33+
window.performance.measure('measure_' + last, 'mark_start_' + last, 'mark_end_' + last);
34+
var items = performance.getEntriesByType('measure');
35+
for (var i = 0; i < items.length; ++i) {
36+
var req = items[i];
37+
duration = req.duration;
38+
console.log(req.name + ' took ' + req.duration + 'ms');
39+
}
40+
performance.clearMeasures();
41+
}, 0);
42+
}
43+
}
44+
45+
export class Row extends React.Component {
46+
constructor(props) {
47+
super(props);
48+
this.click = this.click.bind(this);
49+
this.del = this.del.bind(this);
50+
}
51+
shouldComponentUpdate(nextProps, nextState) {
52+
const {data,styleClass}=this.props;
53+
const nextStyleClass=nextProps.styleClass;
54+
const nextData= nextProps.data;
55+
return data !== nextData||styleClass!=nextStyleClass
56+
}
57+
click() {
58+
this.props.onClick(this.props.data.id);
59+
}
60+
del() {
61+
this.props.onDelete(this.props.data.id);
62+
}
63+
render() {
64+
let {styleClass, onClick, onDelete, data} = this.props;
65+
return (<tr className={styleClass}>
66+
<td className="col-md-1">{data.id}</td>
67+
<td className="col-md-4">
68+
<a onClick={this.click}>{data.label}</a>
69+
</td>
70+
<td className="col-md-1"><a onClick={this.del}><span className="glyphicon glyphicon-remove" aria-hidden="true"></span></a></td>
71+
<td className="col-md-6"></td>
72+
</tr>);
73+
}
74+
}
75+
76+
export class Controller extends React.Component{
77+
constructor(props) {
78+
super(props);
79+
this.select = this.select.bind(this);
80+
this.delete = this.delete.bind(this);
81+
this.add = this.add.bind(this);
82+
this.run = this.run.bind(this);
83+
this.update = this.update.bind(this);
84+
this.runLots = this.runLots.bind(this);
85+
this.clear = this.clear.bind(this);
86+
this.swapRows = this.swapRows.bind(this);
87+
this.componentDidUpdate = this.componentDidUpdate.bind(this);
88+
this.componentDidMount = this.componentDidMount.bind(this);
89+
this.start = 0;
90+
}
91+
shouldComponentUpdate(nextProps, nextState) {
92+
93+
const {data,selected}=this.props;
94+
const nextData= nextProps.data;
95+
const nextSelected= nextProps.selected;
96+
return data !== nextData||selected!=nextSelected;
97+
}
98+
printDuration() {
99+
stopMeasure();
100+
}
101+
componentDidUpdate() {
102+
this.printDuration();
103+
}
104+
componentDidMount() {
105+
this.printDuration();
106+
}
107+
run() {
108+
startMeasure("run");
109+
this.props.run();
110+
}
111+
add() {
112+
startMeasure("add");
113+
this.props.add();
114+
}
115+
update() {
116+
startMeasure("updater");
117+
this.props.update();
118+
}
119+
select(id) {
120+
startMeasure("select");
121+
this.props.select(id);
122+
}
123+
delete(id) {
124+
startMeasure("delete");
125+
this.props.remove(id);
126+
}
127+
runLots() {
128+
startMeasure("runLots");
129+
this.props.runLots();
130+
}
131+
clear() {
132+
startMeasure("clear");
133+
this.props.clear();
134+
}
135+
swapRows() {
136+
startMeasure("swapRows");
137+
this.props.swapRows();
138+
}
139+
render () {
140+
const selected = this.props.selected;
141+
var rows = this.props.data.map((d,i) => {
142+
const id = d.id;
143+
var className = id === selected ? 'danger':'';
144+
return <Row key={id} data={d} onClick={this.select} onDelete={this.delete} styleClass={className}></Row>
145+
})
146+
return (<div className="container">
147+
<div className="jumbotron">
148+
<div className="row">
149+
<div className="col-md-6">
150+
<h1>React + Redux-Combiner</h1>
151+
</div>
152+
<div className="col-md-6">
153+
<div className="row">
154+
<div className="col-sm-6 smallpad">
155+
<button type="button" className="btn btn-primary btn-block" id="run" onClick={this.run}>Create 1,000 rows</button>
156+
</div>
157+
<div className="col-sm-6 smallpad">
158+
<button type="button" className="btn btn-primary btn-block" id="runlots" onClick={this.runLots}>Create 10,000 rows</button>
159+
</div>
160+
<div className="col-sm-6 smallpad">
161+
<button type="button" className="btn btn-primary btn-block" id="add" onClick={this.add}>Append 1,000 rows</button>
162+
</div>
163+
<div className="col-sm-6 smallpad">
164+
<button type="button" className="btn btn-primary btn-block" id="update" onClick={this.update}>Update every 10th row</button>
165+
</div>
166+
<div className="col-sm-6 smallpad">
167+
<button type="button" className="btn btn-primary btn-block" id="clear" onClick={this.clear}>Clear</button>
168+
</div>
169+
<div className="col-sm-6 smallpad">
170+
<button type="button" className="btn btn-primary btn-block" id="swaprows" onClick={this.swapRows}>Swap Rows</button>
171+
</div>
172+
</div>
173+
</div>
174+
</div>
175+
</div>
176+
<table className="table table-hover table-striped test-data">
177+
<tbody>{rows}</tbody>
178+
</table>
179+
<span className="preloadicon glyphicon glyphicon-remove" aria-hidden="true"></span>
180+
</div>);
181+
}
182+
}
183+
184+
export default connect(
185+
state => {
186+
return ({
187+
data: state.store.data,
188+
selected: state.store.selected
189+
})
190+
},
191+
{
192+
buildData: () => buildData(),
193+
remove: id => remove(id),
194+
run: () => run(),
195+
add: () => add(),
196+
update: () => update(),
197+
select: id => select(id),
198+
runLots: () => runLots(),
199+
clear: () => clear(),
200+
swapRows: () => swapRows()
201+
}
202+
)(Controller);
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
'use strict';
2+
3+
import React from "react";
4+
import Controller from './controller';
5+
6+
import ReactDOM from 'react-dom';
7+
import store from './store';
8+
import {Provider} from 'react-redux';
9+
10+
ReactDOM.render(
11+
(
12+
<Provider store={store}>
13+
<Controller />
14+
</Provider>
15+
),
16+
document.getElementById("main")
17+
);
Lines changed: 99 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,99 @@
1+
'use strict';
2+
3+
import { combineReducers, createStore } from 'redux';
4+
import { node, demux } from 'redux-combiner'
5+
import * as utils from './utils.es6'
6+
7+
const BUILD_DATA = 'BUILD_DATA';
8+
const DELETE = 'DELETE';
9+
const RUN = 'RUN';
10+
const ADD = 'ADD';
11+
const UPDATE = 'UPDATE';
12+
const SELECT = 'SELECT';
13+
const RUN_LOTS = 'RUN_LOTS';
14+
const CLEAR = 'CLEAR';
15+
const SWAP_ROWS = 'SWAP_ROWS';
16+
17+
export function buildData() {
18+
return {
19+
type: BUILD_DATA
20+
};
21+
}
22+
23+
export function remove(id) {
24+
return {
25+
type: DELETE,
26+
id
27+
};
28+
}
29+
30+
export function run() {
31+
return {
32+
type: RUN
33+
};
34+
}
35+
36+
export function add() {
37+
return {
38+
type: ADD
39+
};
40+
}
41+
42+
export function update() {
43+
return {
44+
type: UPDATE
45+
}
46+
}
47+
48+
export function select(id) {
49+
return {
50+
type: SELECT,
51+
id
52+
};
53+
}
54+
55+
export function runLots() {
56+
return {
57+
type: RUN_LOTS
58+
};
59+
}
60+
61+
export function clear() {
62+
return {
63+
type: CLEAR
64+
};
65+
}
66+
67+
export function swapRows() {
68+
return {
69+
type: SWAP_ROWS
70+
}
71+
}
72+
73+
const reducer = node({
74+
75+
store: {
76+
77+
data: demux(
78+
[],
79+
{
80+
label: node('')
81+
.on(UPDATE, label => label + ' !!!')
82+
},
83+
utils.every10th
84+
)
85+
.on(DELETE, (data, { id }) => utils.deleteRow(data, id))
86+
.on(RUN, utils.run)
87+
.on(ADD, utils.add)
88+
.on(CLEAR, [])
89+
.on(RUN_LOTS, utils.runLots)
90+
.on(SWAP_ROWS, utils.swapRows),
91+
92+
selected: node(false)
93+
.on(SELECT, (_, { id }) => id)
94+
.on([ RUN, RUN_LOTS, CLEAR ], undefined)
95+
96+
}
97+
})
98+
99+
export default createStore(reducer)

0 commit comments

Comments
 (0)