Friday, April 6, 2018

[React.js] A simple webpage blog with create feature

This is an web single page written by react.js (with ES5,not ES6), shown a webpage with 5 articles, all article content are in hand-code. In my original plan, i want load the data from external json file but finally I feel lazy :p

There are 5 components named Header, Blog, Article, ArticleForm and Footer, html code are rendered by react.js , written in render function. Content like title, content, author are saved in state.

Result interface 

script.jsx
var Header = React.createClass({
  render:function(){
    return (
      <header>
        <h1>Blog name</h1>
      </header>
    );
  }
});

var Blog = React.createClass({
  getInitialState: function(){
    return {
      viewtimes:0,
      articleList:[
        {"title":"Hello World","content":"sdfsddfafadfs","author":"John",
         "updated_at":"23-11-2017 18:05:07","viewtimes":133},
        {"title":"The time is now","content":"dhgjkdhgkdfg","author":"Ann",
         "updated_at":"29-11-2017 03:10:12","viewtimes":112},
        {"title":"God will make a way","content":"sdjghdfjg","author":"Tom",
         "updated_at":"11-11-2017 21:21:26","viewtimes":13},
        {"title":"When you gone","content":"jiouij","author":"Suman",
         "updated_at":"08-11-2017 23:46:15","viewtimes":29},
        {"title":"HahHahaha","content":"zxbnvmnm","author":"May",
         "updated_at":"03-11-2017 09:45:39","viewtimes":56}
      ]
    };
  },
  countViewtimes: function(viewtimes){
    this.setState((prevState) => {
      return { viewtimes: prevState.viewtimes + viewtimes }
    });
  },
  createArticle: function(article){
    this.setState((prevState) => {
      return { articleList:this.state.articleList.concat(article) }
    });
  },
  render:function(){
    var component = this;
    var articles = this.state.articleList.map(function(article){
      return (
        <Article title={article.title} content={article.content}
            author={article.author}
            updated_at={article.updated_at}
            viewtimes={article.viewtimes}
            handleViews={component.countViewtimes} />
        );
    });
    return(
      <div>
        <Header />
        <ArticleForm handleCreate={this.createArticle} />
        {articles}
        <Footer viewtimes={this.state.viewtimes}/>
      </div>
    );
  }
});

var Article = React.createClass({
  getInitialState: function(){
    this.props.handleViews(this.props.viewtimes);
    return {articleAmount:this.props.viewtimes};
  },
  render:function(){
    return (
      <article>
        <h2>{this.props.title}</h2>
        <p>{this.props.content}</p>
        <div className="meta">Last updated by {this.props.author} at {this.props.updated_at}</div>
      </article>
    );
  }
});

var ArticleForm = React.createClass({
  submit: function(e){
    e.preventDefault();
    var article = {"title":this.refs.title.value,
                   "content":this.refs.content.value,
                   "author":"user",
                   "updated_at":new Date().toLocaleString(),
                   "viewtimes":0
     
    };
    this.props.handleCreate(article);
  },
  render: function(){
    return (
      <form onSubmit={this.submit}>
        <input type="text" name="title" placeholder="Title" ref="title"/>
        <textarea name="content" placeholder="Content" ref="content">
        </textarea>
        <br />
        <br />
        <button>Create Article</button>
      </form>
    );
  }
});

var Footer = React.createClass({
  render:function(){
    return (
      <footer>
        <p>This example is hosted in plnkr.co.
          <span>Total viewtimes of the articles : {this.props.viewtimes}</span>
        </p>
      </footer>
    );
  }
});


React.render(<Blog/>, document.getElementById("root"));
 index.html
<!DOCTYPE html>
<html>

  <head>
    <link rel="stylesheet" href="style.css">
  </head>

  <body>
    <div id="root"></div>
    <script src="https://fb.me/react-0.14.3.min.js"></script>
    <script src="https://fb.me/react-dom-0.14.3.min.js"></script>
    <script src="script.js"></script>
  </body>
</html>
style.css
body{background:url(https://i.pinimg.com/736x/8d/34/1d/8d341deaa1952725765134832e2902b6--fine-paper-background-designs.jpg);}
header {text-align:center; font-family: "Source Sans Pro", sans-serif; font-weight: 400; color:#000;}
form{background:rgba(0,0,0,0.5);margin:10px; padding:15px; }
form input {width:100%;margin-bottom:10px;}
form textarea {width:100%;}
article {border:1px solid #aaa; margin:10px; padding:15px; background:rgba(255,255,255,0.8);}
article h2 {border-bottom:1px solid #aaa; padding-bottom:15px;}
article p {border-bottom:1px solid #aaa; padding-bottom:15px;}
article .meta {text-align:right;color:#000;}
footer {text-align:center}

No comments :

Post a Comment