Skip to content

Instantly share code, notes, and snippets.

@yohfee
Last active July 15, 2021 23:45
Show Gist options
  • Save yohfee/43be4349b3cd596c16dc to your computer and use it in GitHub Desktop.
Save yohfee/43be4349b3cd596c16dc to your computer and use it in GitHub Desktop.
* cli
cd src/github.com/yohfee
mkdir react-flux-redo
cd react-flux-redo
* index.html
<!DOCTYPE html>
<html>
<body>
<script src="app.js"></script>
</body>
</html>
* cli
tmux
python -m SimpleHTTPServer
open http://localhost:8000
npm init -f
npm i -D react flux watchify babelify
* package.json
"watch": "watchify main.js -v -t babelify -o app.js",
* main.js
import React from "react";
React.render(<h1>Hello!</h1>, document.body);
* cli
npm run watch
open http://localhost:8000
* main.js
import Form from "./form";
React.render(<Form />, document.body);
* form.js
import React from "react";
export default class Form extends React.Component {
constructor(props) {
super(props);
this.state = { text: "Hi!" };
}
render() {
return (
<div>
<input />
<button>Update</button>
<button>Undo</button>
<button>Redo</button>
<p>{this.state.text}</p>
</div>
);
}
}
* cli
open http://localhost:8000
* dispatcher.js
import { Dispatcher } from "flux";
export default new Dispatcher();
* constants.js
import keymirror from "react/lib/keymirror";
export default keymirror({
});
* constants.js
UPDATE: null,
UNDO: null,
REDO: null
* actions.js
export default {
update(text) {
},
undo() {
},
redo() {
}
};
* actions.js
import Dispatcher from "./dispatcher";
import Constants from "./constants";
Dispatcher.dispatch({
type: Constants.UPDATE,
text: text
});
Dispatcher.dispatch({
type: Constants.UNDO
});
Dispatcher.dispatch({
type: Constants.REDO
});
* form.js
<button onClick={this.update.bind(this)}>Update</button>
<button onClick={this.undo.bind(this)}>Undo</button>
<button onClick={this.redo.bind(this)}>Redo</button>
update() {
}
undo() {
}
redo() {
}
* form.js
import Actions from "./actions";
<input ref="input" />
let input = this.refs.input.getDOMNode();
Actions.update(input.value);
input.value = "";
input.focus();
Actions.undo();
Actions.redo();
* cli
open http://localhost:8000
* store.js
import { EventEmitter } from "events";
import assign from "react/lib/Object.assign";
import Dispatcher from "./dispatcher";
const CHANGE_EVENT = "change";
const Store = assign({}, EventEmitter.prototype, {
emitChange() {
this.emit(CHANGE_EVENT);
},
addChangeListener(callback) {
this.on(CHANGE_EVENT, callback);
},
removeChangeListener(callback) {
this.removeListener(CHANGE_EVENT, callback);
}
});
Store.dispatchToken = Dispatcher.register(function(action) {
switch (action.type) {
default:
break;
}
});
export default Store;
* store.js
import Constants from "./constants";
case Constants.UPDATE:
break;
case Constants.UNDO:
break;
case Constants.REDO:
break;
if (_text !=== action.text) {
update(action.text);
Store.emitChange();
}
undo();
Store.emitChange();
redo();
Store.emitChange();
let _undo = [];
let _redo = [];
let _text = "";
function update(text) {
_undo.push(_text);
_redo.length = 0;
_text = text;
}
function undo() {
_redo.push(_text);
_text = _undo.pop();
}
function redo() {
_undo.push(_text);
_text = _redo.pop();
}
* form.js
import Store from "./store";
function getStateFromStore() {
return {
text: Store.getText()
};
}
this.onChange = this.onChange.bind(this);
this.state = getStateFromStore();
componentDidMount() {
Store.addChangeListener(this.onChange);
}
componentWillUnmount() {
Store.removeChangeListener(this.onChange);
}
onChange() {
this.setState(getStateFromStore());
}
* store.js
getText() {
return _text;
},
* cli
open http://localhost:8000
* store.js
getUndo() {
return _undo;
},
getRedo() {
return _redo;
},
* form.js
undo: Store.getUndo(),
redo: Store.getRedo(),
<p>Undo</p>
<ul>
{this.state.undo.map(t => <li>{t}</li>)}
</ul>
<p>Redo</p>
<ul>
{this.state.redo.map(t => <li>{t}</li>)}
</ul>
* cli
open http://localhost:8000
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment