Created
September 4, 2021 08:41
-
-
Save namse/419fba3478bfb5cf0f12c1ecf2b57f53 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
export {}; | |
// 주제 : multiple counter | |
// update -> render -> event handling -> 반복 | |
type State = { | |
counters: { | |
count: number; | |
}[]; | |
}; | |
type BaseRenderingData = { | |
id: Symbol; | |
}; | |
type TextRenderingData = { | |
type: "text"; | |
value: string; | |
} & BaseRenderingData; | |
type RectRenderingData = { | |
type: "rect"; | |
x: number; | |
y: number; | |
width: number; | |
height: number; | |
} & BaseRenderingData; | |
type RenderingData = TextRenderingData | RectRenderingData; | |
type RenderingDataTree = (RenderingData | RenderingDataTree)[]; | |
function index(state: State): RenderingDataTree { | |
return [ | |
state.counters.map((counterState) => | |
Counter({ | |
state: counterState, | |
onRemove: () => { | |
// case 1. remove by index | |
// problem - what if remove 2 counters, index 3 and 5? it will remove original 3, 6 counter. | |
// case 2. remove by reference | |
state.counters.remove(counterState); | |
}, | |
}) | |
), | |
Button({ | |
x: 20, | |
y: 0, | |
width: 20, | |
height: 20, | |
text: "add counter", | |
onClick: () => { | |
state.counters.push({ count: 0 }); | |
}, | |
}), | |
]; | |
} | |
function Counter({ | |
state, | |
onRemove, | |
}: { | |
state: { count: number }; | |
onRemove: () => void; | |
}): RenderingDataTree { | |
return [ | |
TextComponent(state.count), | |
Button({ | |
x: 20, | |
y: 0, | |
width: 20, | |
height: 20, | |
text: "+", | |
onClick: () => { | |
state.count += 1; | |
}, | |
}), | |
Button({ | |
x: 40, | |
y: 0, | |
width: 20, | |
height: 20, | |
text: "remove", | |
onClick: () => { | |
onRemove(); | |
}, | |
}), | |
]; | |
} | |
function TextComponent(value: string | number): RenderingData { | |
return { | |
id: Symbol(), | |
type: "text", | |
value: value.toString(), | |
}; | |
} | |
function Button({ | |
x, | |
y, | |
width, | |
height, | |
text, | |
onClick, | |
}: { | |
x: number; | |
y: number; | |
width: number; | |
height: number; | |
text: string; | |
onClick: () => void; // 이것을 아래 Rect와 연결해야해 | |
}): RenderingDataTree { | |
return [ | |
Rect({ | |
x, | |
y, | |
width, | |
height, | |
onClick, | |
}), | |
TextComponent(text), | |
]; | |
} | |
function Rect({ | |
x, | |
y, | |
width, | |
height, | |
onClick, | |
}: { | |
x: number; | |
y: number; | |
width: number; | |
height: number; | |
onClick?: () => void; | |
}): RenderingData { | |
const id = Symbol(); | |
onClick && register(id, onClick); | |
return { | |
id, | |
type: "rect", | |
x, | |
y, | |
width, | |
height, | |
}; | |
} | |
function register(id: symbol, onClick: () => void) { | |
throw new Error("Function not implemented."); | |
} | |
declare global { | |
interface Array<T> { | |
remove(o: T): void; | |
} | |
} | |
Array.prototype.remove = function (element) { | |
const index = this.indexOf(element); | |
if (index > -1) { | |
this.splice(index, 1); | |
} | |
}; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment