Skip to content

Instantly share code, notes, and snippets.

@cyan33
Created June 10, 2018 22:46
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save cyan33/e60793d5e8c9e62a228db63f8f1983c1 to your computer and use it in GitHub Desktop.
Save cyan33/e60793d5e8c9e62a228db63f8f1983c1 to your computer and use it in GitHub Desktop.
state tracking, undo, redo state changes in React
import React from "react";
import ReactDOM from "react-dom";
class App extends React.Component {
state = {
pointer: -1,
stateQueue: [],
currentState: { count: 0 }
};
componentDidUpdate(prevProps, prevState) {
const { stateQueue, pointer } = this.state;
if (pointer === prevState.pointer) {
return;
}
this.setState({
currentState: stateQueue[pointer]
});
}
addCounter = () => {
// CAVEAT:
// if the pointer is not at the end of the stateQueue,
// we'll need to detach all of the state changes after pointer
this.setState(
state => {
return {
pointer: state.pointer + 1,
stateQueue:
state.pointer === state.stateQueue.length - 1
? state.stateQueue.concat({
count: state.currentState.count + 1
})
: state.stateQueue.slice(0, state.pointer + 1).concat({
count: state.currentState.count + 1
})
};
},
() => console.log(this.state)
);
};
undoState = () => {
if (this.state.pointer - 1 < 0) {
console.warn(`cannot undo anymore`);
return;
}
this.setState(
state => ({
pointer: state.pointer - 1
}),
() => console.log(this.state)
);
};
redoState = () => {
const { pointer, stateQueue } = this.state;
if (pointer + 1 > stateQueue.length - 1) {
console.warn(`cannot redo anymore`);
return;
}
this.setState(
state => ({
pointer: state.pointer + 1
}),
() => console.log(this.state)
);
};
render() {
return (
<div className="App">
<h2>Counter: {this.state.currentState.count}</h2>
<button onClick={this.addCounter}>Add</button>
<button onClick={this.undoState}>Undo</button>
<button onClick={this.redoState}>Redo</button>
</div>
);
}
}
const rootElement = document.getElementById("root");
ReactDOM.render(<App />, rootElement);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment