don't re-compute values on first render (unnecessary, values are part of state)
This commit is contained in:
parent
174bab79e4
commit
2d0deca127
14 changed files with 274 additions and 115 deletions
66
src/App.tsx
66
src/App.tsx
|
|
@ -1,16 +1,47 @@
|
|||
import { useEffect, useRef, useState } from 'react';
|
||||
import { useEffect, useState } from 'react';
|
||||
import './App.css'
|
||||
import { Editor, type EditorState } from './Editor'
|
||||
import { initialEditorState, nonEmptyEditorState, tripleFunctionCallEditorState } from "./configurations";
|
||||
import { CommandContext } from './CommandContext';
|
||||
import { EnvContext } from './EnvContext';
|
||||
import { deserialize, serialize } from './types';
|
||||
import { extendedEnv } from './EnvContext';
|
||||
import { useEffectBetter } from './util/use_effect_better';
|
||||
|
||||
const commands: [string, string[], string][] = [
|
||||
["call" , ['c' ], "call" ],
|
||||
["eval" , ['e','Tab','Enter'], "eval" ],
|
||||
["transform", ['t', '.' ], "transform" ],
|
||||
["let" , ['l', '=', 'a' ], "let ... in ..."],
|
||||
];
|
||||
|
||||
const examples: [string, EditorState][] = [
|
||||
["empty editor", initialEditorState],
|
||||
["push to list", nonEmptyEditorState],
|
||||
["function w/ 4 params", tripleFunctionCallEditorState]];
|
||||
|
||||
export function App() {
|
||||
// const [history, setHistory] = useState([initialEditorState]);
|
||||
// const [history, setHistory] = useState([nonEmptyEditorState]);
|
||||
const [history, setHistory] = useState([tripleFunctionCallEditorState]);
|
||||
// const [history, setHistory] = useState([tripleFunctionCallEditorState]);
|
||||
// const [future, setFuture] = useState<EditorState[]>([]);
|
||||
|
||||
const [future, setFuture] = useState<EditorState[]>([]);
|
||||
// load from localStorage
|
||||
const [history, setHistory] = useState<EditorState[]>(
|
||||
localStorage["history"]
|
||||
? JSON.parse(localStorage["history"]).map(s => deserialize(s, extendedEnv))
|
||||
: [initialEditorState]
|
||||
);
|
||||
const [future, setFuture] = useState<EditorState[]>(
|
||||
localStorage["future"]
|
||||
? JSON.parse(localStorage["future"]).map(s => deserialize(s, extendedEnv))
|
||||
: []
|
||||
);
|
||||
|
||||
useEffectBetter(() => {
|
||||
// persist accross reloads
|
||||
localStorage["history"] = JSON.stringify(history.map(serialize));
|
||||
localStorage["future"] = JSON.stringify(future.map(serialize));
|
||||
}, [history, future]);
|
||||
|
||||
const pushHistory = (callback: (p: EditorState) => EditorState) => {
|
||||
const newState = callback(history.at(-1)!);
|
||||
|
|
@ -51,12 +82,6 @@ export function App() {
|
|||
window.onkeydown = onKeyDown;
|
||||
}, []);
|
||||
|
||||
const commands: [string, string[], string][] = [
|
||||
["call" , ['c' ], "call" ],
|
||||
["eval" , ['e','Tab','Enter' ], "eval" ],
|
||||
["transform", ['t', '.' ], "transform" ],
|
||||
["let" , ['l', '=', 'a' ], "let ... in ..."],
|
||||
];
|
||||
|
||||
const [highlighted, setHighlighted] = useState(
|
||||
commands.map(() => false));
|
||||
|
|
@ -68,12 +93,16 @@ export function App() {
|
|||
}];
|
||||
}));
|
||||
|
||||
const onSelectExample = (e: React.SyntheticEvent<HTMLSelectElement>) => {
|
||||
// @ts-ignore
|
||||
pushHistory(_ => examples[e.target.value][1]);
|
||||
}
|
||||
|
||||
return (
|
||||
<>
|
||||
<header>
|
||||
<button disabled={history.length===1} onClick={onUndo}>Undo ({history.length-1}) [Ctrl+Z]</button>
|
||||
<button disabled={future.length===0} onClick={onRedo}>Redo ({future.length}) [Ctrl+Shift+Z]</button>
|
||||
Commands:
|
||||
<button disabled={history.length===1} onClick={onUndo}>Undo ({history.length-1}) <kbd>Ctrl</kbd>+<kbd>Z</kbd></button>
|
||||
<button disabled={future.length===0} onClick={onRedo}>Redo ({future.length}) <kbd>Ctrl</kbd>+<kbd>Shift</kbd>+<kbd>Z</kbd></button>
|
||||
{
|
||||
commands.map(([_, keys, descr], i) =>
|
||||
<span key={i} className={'command' + (highlighted[i] ? (' highlighted') : '')}>
|
||||
|
|
@ -81,6 +110,17 @@ export function App() {
|
|||
{descr}
|
||||
</span>)
|
||||
}
|
||||
<select onClick={onSelectExample}>
|
||||
{
|
||||
examples.map(([name], i) => {
|
||||
return <option key={i} value={i}>{name}</option>;
|
||||
})
|
||||
}
|
||||
</select>
|
||||
<button className="factoryReset" onClick={() => {
|
||||
setHistory(_ => [initialEditorState]);
|
||||
setFuture(_ => []);
|
||||
}}>FACTORY RESET</button>
|
||||
</header>
|
||||
|
||||
<main onKeyDown={onKeyDown}>
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue