Fork me on GitHub

ReactJS tutorial in ki

The index.html page:

    <title>Hello React</title>
    <script src=""></script>
    <script src=""></script>
    <script src="mori.js"></script>
    <div id="content"></div>
    <script src="react_ki.out.js"></script>

A few macros for writing React components concisely using s-expressions instead of JSX

ki macro (defcomp $name $render_body) 
         (def $name ((js React.createClass) 
                     {$ 'render' (fn [] $render_body)}))
ki macro (defcomp $name {$kv ...} $render_body) 
         (def $name ((js React.createClass) 
                     {$kv ... 'render' (fn [] $render_body)}))
ki macro (dom $tag {$kv ...} $children ...)
         ((js React.DOM.$tag) {$kv ...} $children ...)
ki macro (dom $tag $children ...)
         ((js React.DOM.$tag) (js {}) $children ...)

Tutorial code starts here. A few things to note:

In a more elaborate version global state could be moved to an atom using atom callbacks to trigger a re-rendering.

ki require core

ki (do

 (def data [{:author "Pete Hunt" :text "This is one comment"}
            {:author "Jordan Walke" :text "This is another comment"}])

 (defcomp Comment
  (dom div {$ :className 'comment'} 
   (dom h2 {$ :className 'commentAuthor'} 

 (defcomp CommentList
  (dom div {$ :className 'commentList'} 
    (map (fn [comment i] 
          (Comment {$ :author (get comment :author)} (get comment :text)))

 (defcomp CommentForm
  {$ :handleSubmit 
      (fn []
       (let [author (js
             text (js this.refs.text.getDOMNode().value.trim())]
        (this.props.onCommentSubmit {:author author :text text})
        (js = '')
        (js this.refs.text.getDOMNode().value = '')
  (dom form {$ :className 'commentForm' :onSubmit this.handleSubmit} 
   (dom input {$ :type 'text' :placeholder 'Your name' :ref 'author'})
   (dom input {$ :type 'text' :placeholder 'Say something...' :ref 'text'})
   (dom input {$ :type 'submit' :value 'Post'})))

 (defcomp CommentBox 
  {$ :getInitialState
      (fn [] 
       {$ :data [{:author "Pete Hunt" :text "This is one comment"}]})
      (fn [] 
       (setTimeout (fnth [] (this.setState {$ :data data})) 1000))
      (fn [comment] 
       (this.setState {$ data (conj comment)}))}
  (dom div {$ :className 'commentBox'} 
   (dom h1 'Comments') 
   (CommentList {$ :data}) 
   (CommentForm {$ :onCommentSubmit this.handleCommentSubmit})))

 (React.renderComponent (CommentBox) (document.getElementById 'content'))