github.com/jgarto/itcv@v0.0.0-20180826224514-4eea09c1aa0d/examples/todoapp/todo_app.go (about) 1 package todoapp // import "myitcv.io/react/examples/todoapp" 2 3 import ( 4 "fmt" 5 6 "honnef.co/go/js/dom" 7 "myitcv.io/react" 8 ) 9 10 //go:generate reactGen 11 12 // TodoAppDef is the definition fo the TodoApp component 13 type TodoAppDef struct { 14 react.ComponentDef 15 } 16 17 // TodoAppState is the state type for the TodoApp component 18 type TodoAppState struct { 19 items []string 20 currItem string 21 } 22 23 // TodoApp creates instances of the TodoApp component 24 func TodoApp() *TodoAppElem { 25 return buildTodoAppElem() 26 } 27 28 // Equals must be defined because struct val instances of TodoAppState cannot 29 // be compared. It is generally bad practice to have mutable values in state in 30 // this way; myitcv.io/immutable seeks to help address this problem. 31 // See myitcv.io/react/examples/immtodoapp for an example 32 func (c TodoAppState) Equals(v TodoAppState) bool { 33 if c.currItem != v.currItem { 34 return false 35 } 36 37 if len(v.items) != len(c.items) { 38 return false 39 } 40 41 for i := range v.items { 42 if v.items[i] != c.items[i] { 43 return false 44 } 45 } 46 47 return true 48 } 49 50 // Render renders the TodoApp component 51 func (t TodoAppDef) Render() react.Element { 52 var entries []react.RendersLi 53 54 for _, v := range t.State().items { 55 entry := react.Li(nil, react.S(v)) 56 entries = append(entries, entry) 57 } 58 59 return react.Fragment( 60 react.H3(nil, react.S("TODO")), 61 react.Ul(nil, entries...), 62 react.Form(&react.FormProps{ClassName: "form-inline"}, 63 react.Div( 64 &react.DivProps{ClassName: "form-group"}, 65 react.Label(&react.LabelProps{ClassName: "sr-only", For: "todoText"}, react.S("Todo Item")), 66 react.Input(&react.InputProps{ 67 Type: "text", 68 ClassName: "form-control", 69 ID: "todoText", 70 Placeholder: "Todo Item", 71 Value: t.State().currItem, 72 OnChange: inputChange{t}, 73 }), 74 react.Button(&react.ButtonProps{ 75 Type: "submit", 76 ClassName: "btn btn-default", 77 OnClick: add{t}, 78 }, react.S(fmt.Sprintf("Add #%v", len(t.State().items)+1))), 79 ), 80 ), 81 ) 82 } 83 84 type inputChange struct{ t TodoAppDef } 85 type add struct{ t TodoAppDef } 86 87 func (i inputChange) OnChange(se *react.SyntheticEvent) { 88 target := se.Target().(*dom.HTMLInputElement) 89 90 ns := i.t.State() 91 ns.currItem = target.Value 92 93 i.t.SetState(ns) 94 } 95 96 func (a add) OnClick(se *react.SyntheticMouseEvent) { 97 ns := a.t.State() 98 ns.items = append(ns.items, ns.currItem) 99 ns.currItem = "" 100 101 a.t.SetState(ns) 102 103 se.PreventDefault() 104 }