React起手式:來寫個TodoList吧

在過去的一年中兄淫,Vue的火熱讓人印象深刻屯远,但是React在github上王者地位依然鞏固,在本文發(fā)布前擁有5.7W個??捕虽,在當(dāng)下依然是最熱門的Javascript框架。本文將從最基礎(chǔ)的點(diǎn)講起并且盡量用簡短的篇幅坡脐,一步步完成一個簡單的TodoList :D

來自Google trend
Screenshot

準(zhǔn)備工作

首先新建一個項(xiàng)目泄私,項(xiàng)目結(jié)構(gòu)如下:

.
├── dist
├── index.html  //主頁面
├── package.json
├── src
│   ├── components
│   ├── vendor
│   ├── styles
│   └── entry.js  //源js文件
└── webpack.config.js

** index.html ** 代碼如下:

<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8">
    <title>TodoList</title>
  </head>
  <body>
    <div id="container">

    </div>
    <script src="./dist/bundle.js"></script>
  </body>
</html>

** package.json ** 代碼如下,使用 * npm install * 安裝好依賴包:

{
  "name": "react-todos",
  "version": "1.0.0",
  "description": "test",
  "main": "index.js",
  "scripts": {
    "dev": "webpack && node server.js"
  },
  "author": "",
  "license": "ISC",
  "dependencies": {
    "react": "^15.4.1",
    "react-dom": "^15.4.1",
    "sass": "^0.5.0",
  },
  "devDependencies": {
    "babel-core": "^5.5.8",
    "babel-loader": "^5.1.4",
    "css-loader": "^0.14.5",
    "express": "^4.14.0",
    "extract-text-webpack-plugin": "^1.0.1",
    "file-loader": "^0.8.4",
    "jsx-loader": "^0.13.2",
    "node-libs-browser": "^0.5.2",
    "node-sass": "^3.2.0",
    "react-redux": "^5.0.1",
    "sass-loader": "^1.0.4",
    "style-loader": "^0.12.3",
    "url-loader": "^0.5.6",
    "webpack": "^1.9.11"
  }
}

webpack配置

webpack是當(dāng)下流行的打包工具备闲,使用webpack可以幫助我們模塊化代碼晌端、解析依賴、壓縮代碼等等恬砂,這里我們使用webpack將JSX語法轉(zhuǎn)換成純Javascript代碼咧纠,如果對webpack不太熟悉的可以先行了解下用法。其配置代碼如下:

const path = require('path');

module.exports = {
    entry: './src/entry.js',
    output: {
        path: path.join(__dirname, '/dist'),
        filename: 'bundle.js'
    },
    resolve: {
        extensions: ['', '.js', '.jsx']
    },
    module: {
        loaders: [
            {
              test: /\.js|jsx$/,
              loaders: ['babel']
             },
            {
              test: /\.scss$/,
              loaders: ['style-loader', 'css-loader', 'sass-loader']
             }
        ]
    }
}

JSX語法

JSX語法泻骤,像是在Javascript代碼里直接寫XML的語法漆羔,實(shí)質(zhì)上這只是一個語法糖,每一個XML標(biāo)簽都會被JSX轉(zhuǎn)換工具轉(zhuǎn)換成純Javascript代碼狱掂,React 官方推薦使用JSX演痒, 當(dāng)然你想直接使用純Javascript代碼寫也是可以的,只是使用JSX趋惨,組件的結(jié)構(gòu)和組件之間的關(guān)系看上去更加清晰鸟顺。使用JSX編寫的代碼長這樣:

React.render(
    <div>
        <div>
            <div>content</div>
        </div>
    </div>,
    document.getElementById('example')
);

搭建基本結(jié)構(gòu)

做好了上述的準(zhǔn)備工作和知識了解后,就可以開始編寫代碼了器虾。
TodoList有用戶提交的表單和列表讯嫂,先把基本的骨架寫好,之后在逐個完善兆沙,在 ** entry.js ** 寫入以下代碼:

import React, { Component } from 'react'
import { render } from 'react-dom'

// 父組件
class ListBox extends Component {
  render() {
    return(
      <div>
        <h1>React-todoList</h1>
        <ListForm />
        <List />
      </div>
    )
  }
}

// 表單組件
class ListForm extends Component {
  render() {
    return(
      <h2>This is ListForm</h2>
    )
  }
}

// 列表組件
class List extends Component {
  render() {
    return(
      <h2>This is List</h2>
    )
  }
}

render(
  <ListBox />,document.getElementById('container')
)

以上的代碼就是寫好了ListBox父組件欧芽,和兩個子組件,最后調(diào)用render函數(shù)將它們都渲染到頁面上挤悉。
執(zhí)行webpack打包后渐裸,打開 ** index.html ** 在瀏覽器可以看到以下效果巫湘。

基礎(chǔ)結(jié)構(gòu).png

列表循環(huán)渲染

列表里面有多條todo,而且是動態(tài)渲染的昏鹃,首先我們在父組件的構(gòu)造函數(shù)中模擬一個假數(shù)據(jù)data來集中管理尚氛,然后用data屬性傳遞給子組件:

class ListBox extends Component {
  constructor(props) {
    super(props)
    this.state = {
      data: [
        {author: "John", text: "This is first todo"},
        {author: "Allen", text: "This is second todo"}
      ]
    }
  }
  render() {
    return(
      <div>
        <h1>React-todoList</h1>
        <ListForm />
        <List data={this.state.data}/>
      </div>
    )
  }
}

在子組件中使用 ** this.props.data ** 接收到父組件數(shù)據(jù),然后循環(huán)遍歷出來:

class List extends Component {
  render() {
    let todoNodes = this.props.data.map(function(item, index){
      return(
        <div key={index}>
          <h2>{ item.author }</h2>
          <p>{ item.text }</p>
        </div>
      )
    })
    return(
      <div>
        {todoNodes}
      </div>
    )
  }
}

PS:大家可能會注意到 <div key={index}> 洞渤,是因?yàn)樵赗eact中數(shù)組遍歷出來的節(jié)點(diǎn)需要定義一個唯一的 key 屬性阅嘶,這里我用的是index。
webpack打包好后载迄,可以在頁面上看到data里面的數(shù)據(jù)都已經(jīng)被渲染出來了:

列表渲染

表單提交

在表單中我們需要兩個輸入框和一個提交按鈕讯柔,還需要綁定提交事件,將輸入框的內(nèi)容提交給父組件:

class ListForm extends Component {
  handleSubmit(e){
    e.preventDefault()  

    let author = this.refs.author.value.trim()
    let text = this.refs.text.value.trim()

    if(!author && !text){
      alert('please confirm input box non-blank')
      return
    }

    //pass value to ListBox
    this.props.onTodoSubmit({
      author: author,
      text: text
    })

    //clear input
    this.refs.author.value = ''
    this.refs.text.value = ''
  }
  render() {
    return (
      <form onSubmit={this.onTodoSubmit.bind(this)}>
        <div>
          <input type="text" placeholder="Name" ref="author" required/>
        </div>
        <div>
          <input type="text" placeholder="What to do..." ref="text" required/>
        </div>
        <input type="submit" value="Post" className="submit-btn"/>
      </form>
    )
  }
}

在html中寫好了一個表格护昧,綁定了一個提交事件 handleSubmit魂迄,在兩個輸入框中分別定義了 ref 屬性方便操作dom。
在提交事件中首先是阻止了默認(rèn)事件惋耙,通過 this.refs 操作dom節(jié)點(diǎn)拿到輸入框內(nèi)容捣炬,再調(diào)用父組件的 onTodoSubmit 函數(shù)將數(shù)據(jù)傳遞過去。

數(shù)據(jù)處理

現(xiàn)在要做的就是在ListBox傳遞 onTodoSubmit 屬性绽榛,并且寫好數(shù)據(jù)處理的函數(shù)就ok了:

class ListBox extends Component {
  constructor(props) {
    super(props)
    this.state = {
      data: [
        {author: "John", text: "This is first todo"},
        {author: "Allen", text: "This is second todo"}
      ]
    }
  }
  handleTodoSubmit(todo) {
    let data = Object.assign([], this.state.data)
    data.push(todo)
    this.setState({ data: data })
  }
  render() {
    return(
      <div>
        <h1>React-todoList</h1>
        <ListForm onTodoSubmit={this.handleTodoSubmit.bind(this)}/>
        <List data={this.state.data}/>
      </div>
    )
  }
}
Congratulation :D

至此一個React版的TodoList就完成了湿酸,在填寫好表單后點(diǎn)擊提交,頁面就會實(shí)時更新了灭美,其實(shí)還可以再修改下樣式和豐富一下功能推溃,比如:本地存儲、刪除todo等等届腐。對于React我也是處在摸索階段铁坎,如果文中出現(xiàn)錯誤的地方,希望大家提出來梯捕,我會馬上修改厢呵。
源碼放在了Github,如果這篇文章對您有幫助的話傀顾,可以點(diǎn)個??支持一下謝謝哈襟铭。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市短曾,隨后出現(xiàn)的幾起案子寒砖,更是在濱河造成了極大的恐慌,老刑警劉巖嫉拐,帶你破解...
    沈念sama閱讀 218,682評論 6 507
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件哩都,死亡現(xiàn)場離奇詭異,居然都是意外死亡婉徘,警方通過查閱死者的電腦和手機(jī)漠嵌,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,277評論 3 395
  • 文/潘曉璐 我一進(jìn)店門咐汞,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人儒鹿,你說我怎么就攤上這事化撕。” “怎么了约炎?”我有些...
    開封第一講書人閱讀 165,083評論 0 355
  • 文/不壞的土叔 我叫張陵植阴,是天一觀的道長。 經(jīng)常有香客問我圾浅,道長掠手,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,763評論 1 295
  • 正文 為了忘掉前任狸捕,我火速辦了婚禮喷鸽,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘灸拍。我一直安慰自己魁衙,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,785評論 6 392
  • 文/花漫 我一把揭開白布株搔。 她就那樣靜靜地躺著,像睡著了一般纯蛾。 火紅的嫁衣襯著肌膚如雪纤房。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,624評論 1 305
  • 那天翻诉,我揣著相機(jī)與錄音炮姨,去河邊找鬼。 笑死碰煌,一個胖子當(dāng)著我的面吹牛舒岸,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播芦圾,決...
    沈念sama閱讀 40,358評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼蛾派,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了个少?” 一聲冷哼從身側(cè)響起洪乍,我...
    開封第一講書人閱讀 39,261評論 0 276
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎夜焦,沒想到半個月后壳澳,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,722評論 1 315
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡茫经,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,900評論 3 336
  • 正文 我和宋清朗相戀三年巷波,在試婚紗的時候發(fā)現(xiàn)自己被綠了萎津。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 40,030評論 1 350
  • 序言:一個原本活蹦亂跳的男人離奇死亡抹镊,死狀恐怖锉屈,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情髓考,我是刑警寧澤部念,帶...
    沈念sama閱讀 35,737評論 5 346
  • 正文 年R本政府宣布,位于F島的核電站氨菇,受9級特大地震影響儡炼,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜查蓉,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,360評論 3 330
  • 文/蒙蒙 一乌询、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧豌研,春花似錦妹田、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,941評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至霜浴,卻和暖如春晶衷,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背阴孟。 一陣腳步聲響...
    開封第一講書人閱讀 33,057評論 1 270
  • 我被黑心中介騙來泰國打工晌纫, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人永丝。 一個月前我還...
    沈念sama閱讀 48,237評論 3 371
  • 正文 我出身青樓锹漱,卻偏偏與公主長得像,于是被迫代替她去往敵國和親慕嚷。 傳聞我的和親對象是個殘疾皇子哥牍,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,976評論 2 355

推薦閱讀更多精彩內(nèi)容