Skip to content

Instantly share code, notes, and snippets.

@PatrickJS
Forked from iammerrick/README.md
Created March 22, 2016 18:30
Show Gist options
  • Select an option

  • Save PatrickJS/73f071088956e6936f8b to your computer and use it in GitHub Desktop.

Select an option

Save PatrickJS/73f071088956e6936f8b to your computer and use it in GitHub Desktop.

Redux Chaos Monkey

This is a proof of concept which allows you to replay system events in a random order each time to make sure your UI can tolerate variable states.

I'm not sure if this is worthy of its on open source project with additional features like changing play back time, whitelisting/blacklisting actions etc but figured I'd put this out there to see if it piques anyones interest.

See a video of this in action here: [https://www.youtube.com/watch?v=wkoukONfwmA](Video on YouTube).

import React from 'react';
import ReactDOM from 'react-dom';
import { createStore, compose } from 'redux';
import { connect, Provider} from 'react-redux';
import { createDevTools, ActionCreators } from 'redux-devtools';
const { reset, performAction } = ActionCreators;
/**
* Developer Tools
*/
const Havoc = connect((state) => state, {
reset,
performAction
})(class extends React.Component {
constructor(){
super(...arguments);
this.havoc = this.havoc.bind(this);
}
havoc() {
const goHam = (list) => {
const keys = Object.keys(list);
const random = keys[Math.floor(Math.random() * keys.length)];
if (keys.length === 0) return null;
if (list[random].action.type !== '@@INIT') {
this.props.performAction(list[random].action);
}
const remaining = keys.reduce((acc, key) => {
if (key === random) return acc;
acc[key] = list[key];
return acc;
}, {});
setTimeout(() => goHam(remaining), 500);
};
this.props.reset();
goHam(this.props.actionsById);
}
render() {
return (
<div style={{ backgroundColor: '#eee' }}>
<button onClick={this.havoc}>Wreak Chaos</button>
{Object.keys(this.props.actionsById).map((action) => {
return <div key={action}>{this.props.actionsById[action].action.type}</div>;
})}
</div>
);
}
});
Havoc.update = () => {};
const DeveloperTools = createDevTools(<Havoc />);
const finalCreateStore = compose(
DeveloperTools.instrument()
)(createStore);
/**
* Constants
*/
const INCREMENT = 'INCREMENT';
const DECREMENT = 'DECREMENT';
/**
* Store
*/
const store = finalCreateStore((state = { count: 0 }, action) => {
switch (action.type) {
case INCREMENT:
return { count: state.count + 1 };
case DECREMENT:
return { count: state.count - 1 };
default:
return state;
}
});
/**
* Actions
*/
const increment = () => {
return {
type: INCREMENT
};
};
const decrement = () => {
return {
type: DECREMENT
};
};
/**
* Selectors
*/
const selectCount = (state) => {
return state.count;
};
/**
* Components
*/
const Counter = connect((state) => ({
count: selectCount(state)
}), {
increment,
decrement
})(class extends React.Component {
render() {
return (
<div>
<button onClick={this.props.increment}>+</button>
<button onClick={this.props.decrement}>-</button>
{this.props.count}
</div>
);
}
});
ReactDOM.render(
<Provider store={store}>
<div>
<Counter />
<DeveloperTools />
</div>
</Provider>
, document.getElementById('viewport'));
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment