Quantity: {this.state.qty}
Price per item: ${this.props.price}
摘要:組建屬性初始化默認值類型在中將下面的代碼替換成下面的代碼最后一步將初始狀態從構造函數中轉變成屬性初始化。在構造函數的后天添加正確的代碼你需要把狀態初始化代碼從構造函數中刪除。
這是React和ECMAScript6結合使用系列文章的第二篇。
下面是所有系列文章章節的鏈接:
React 、 ES6 - 介紹(第一部分)
React類、ES7屬性初始化(第二部分)
React類,方法綁定(第三部分)
ES6中React Mixins的使用(第四部分)
React 和ES6 之JSPM的使用(第五部分)
React 和 ES6 工作流之 Webpack的使用(第六部分)
本篇文章Github源碼
React | JS |
---|---|
在第一篇文章中,我們開始介紹如何使用ES6來創建靜態的組建并且輸出Hello from ES6. Not so exciting :)
在這篇文章中,我們將創建一個名字叫做CartItem的更復雜的組建。它將輸出購物車中的一些產品信息,包括圖片、標題和價格。
此外,用戶可以和CartItem組建交互,通過點擊增加或者減少改變items的數量。并且我們的組建將對交互后的總價格做出動態改變。
最后的項目效果圖:
創建index.html文件讓我們來創建一個簡單的html模版文件。
React and ES6 Part 2
注意我們已經通過cdn添加了Foundation CSS框架服務.它可以讓我們微應用看起來很漂亮。同時,class為root的div將是我們應用加載的地方。
Gulpfile.js創建gulpfile.js文件,拷貝下面的代碼到gulpfile.js文件中。
var gulp = require("gulp"); var browserify = require("browserify"); var babelify = require("babelify"); var source = require("vinyl-source-stream"); gulp.task("build", function () { return browserify({entries: "./app.jsx", extensions: [".jsx"], debug: true}) .transform("babelify", {presets: ["es2015", "react"]}) .bundle() .on("error", function(err) { console.error(err); this.emit("end"); }) .pipe(source("bundle.js")) .pipe(gulp.dest("dist")); }); gulp.task("watch", ["build"], function () { gulp.watch("*.jsx", ["build"]); }); gulp.task("default", ["watch"]);package.json
創建一個空文件夾,切換到這個文件夾中,在終端輸入npm init初始化你的package.json。
運行npm install --save react react-dom,這將安裝react和react-dom到你的node_modules文件夾并且作為依賴庫保存到package.json文件中。
運行npm install --save-dev gulp browserify babelify vinyl-source-stream babel-preset-es2015 babel-preset-react,這將安裝更多的依賴到你的node_modules文件夾。
Main application React Component創建app.jsx:
import React from "react"; import ReactDOM from "react-dom"; import CartItem from "./cartItem"; const order = { title: "Fresh fruits package", image: "http://images.all-free-download.com/images/graphiclarge/citrus_fruit_184416.jpg", initialQty: 3, price: 8 }; ReactDOM.render(, document.querySelector(".root") );
上面的代碼做了什么:
Lines 1-2. 我們導入 React / ReactDOM 庫。
Line 3. 導入我們馬上要創建的CartItem組建。
Lines 5-10. 給CartItem組建設置相關屬性(屬性包括 item title, image, initial quantity and price).
Lines 12-18. 加載CartItem組建到一個CSS類為root的DOM元素上。
CartItem React Component 架構現在是創建負責顯示項目的數據以及與用戶的交互組件的時候了。
添加下面的代碼到cartItem.jsx文件中:
import React from "react"; export default class CartItem extends React.Component { constructor(props) { super(props); this.state = { qty: props.initialQty, total: 0 }; } componentWillMount() { this.recalculateTotal(); } increaseQty() { this.setState({qty: this.state.qty + 1}, this.recalculateTotal); } decreaseQty() { let newQty = this.state.qty > 0 ? this.state.qty - 1 : 0; this.setState({qty: newQty}, this.recalculateTotal); } recalculateTotal() { this.setState({total: this.state.qty * this.props.price}); } }
代碼解釋:
Lines 4-10. 這是ES6中React類的構造函數。super(props)這句代碼是先處理父類的props,這句代碼必不可少。下面的狀態機變量的設置相當于ES5中getInitialState()方法狀態機變量的初始化,我們通過this.state來給狀態機變量設置初始值。個人意見,我比較喜歡ES6中構造函數的寫法。
Lines 11-13. componentWillMount()是生命周期中的方法,在這個方法里面我們通過recalculateTotal()方法對總價格做了計算。
Lines 14-20. 給用戶提供增加和減少的交互方法。當用戶點擊相應的按鈕(如前面的效果圖所示)時,這兩個方法會被調用。
CartItem render method在CartItem類中添加新的方法:
export default class CartItem extends React.Component { // previous code we wrote here render() { return () } } Quantity: {this.state.qty}
Price per item: ${this.props.price}
Total: ${this.state.total}
這里我們只是使用JSX+組建,再加上一些基礎的CSS輸出漂亮的標簽。
不要擔心{this.increaseQty.bind(this)}這句代碼的使用,下一小結中我們將會詳細講解,現在你需要相信我,這句代碼會調用CartItem類中的increaseQty()方法即可。
因此,到現在我們已經有了和用戶交互的漂亮的應用了,它向我們展示了如何使用ECMAScript6來編寫React 組建。就我個人而言,我很喜歡ES6帶來的新的語法。
到現在我們還沒有完成。在完成這篇文章之前,我們將再看看ES6中其它的一些新的特性。
Default Props and Prop Types for ES6 React classes想象我們想要為CartItem組建添加一些驗證和默認值。
幸運的是,你只需要在CartItem類中添加如下代碼即可。
static get defaultProps() { return { title: "Undefined Product", price: 100, initialQty: 0 } } static propTypes = { title: React.PropTypes.string.isRequired, price: React.PropTypes.number.isRequired, initialQty: React.PropTypes.number }
PS: 也可以將上面的代碼刪除,在cartItem里面非CartItem類的內部添加如下代碼:
CartItem.defaultProps = { title: "Undefined Product", price: 100, initialQty: 0 } CartItem.propTypes = { title: React.PropTypes.string.isRequired, price: React.PropTypes.number.isRequired, initialQty: React.PropTypes.number }
就我個人而言,比較喜歡第一種寫法,它不會破壞類的封裝性。
添加上面的代碼后,如果你給title屬性添加numeric類型的值,將在控制臺出現警告,這就是React屬性驗證的功能。
Bringing ES7 into the project你可能會問一個合理的問題,為什么ES6還沒有定稿,在你的標題中為什么出現ES7呢?
我會告訴你,讓我們展望未來。我們開始使用non-breaking、property initializers和decorators的新特性。
即使ES7還處于非常早期的階段,在Babel中已經實現了部分的建議性的新特性。這些實驗性的新特性是從ES5到ES7令人驚嘆的新的特性的轉變。
首先,通過npm install --save-dev babel-preset-stage-0命令安裝缺失的npm module。
其次,為了在我們項目中能夠使用新的語法,我們需要在gulpfile.js文件的第8行做一些改變,代碼如下:
.transform("babelify", {presets: ["react", "es2015", "stage-0"]})
你可以從GitHub repository直接拷貝gulpfile.js完整的代碼。
ES7 React 組建屬性初始化/默認值/類型Inside class add this right above :
在CartItem中將下面的代碼:
static get defaultProps() { return { title: "Undefined Product", price: 100, initialQty: 0 } } static propTypes = { title: React.PropTypes.string.isRequired, price: React.PropTypes.number.isRequired, initialQty: React.PropTypes.number }
替換成下面的代碼:
static propTypes = { title: React.PropTypes.string.isRequired, price: React.PropTypes.number.isRequired, initialQty: React.PropTypes.number }; static defaultProps = { title: "Undefined Product", price: 100, initialQty: 0 };ES7 Property Initialiazers for initial state of React component
最后一步將初始狀態從構造函數中轉變成屬性初始化。
在CartItem構造函數的后天添加正確的代碼:
export default class CartItem extends React.Component { // .. constructor starts here state = { qty: this.props.initialQty, total: 0 }; // .. some code here
你需要把狀態初始化代碼從構造函數中刪除。
最后你需要檢查一下cartItem.jsx文件里面完整的代碼:
import React from "react"; export default class CartItem extends React.Component { constructor(props) { super(props); } state = { qty: this.props.initialQty, total: 0 }; static propTypes = { title: React.PropTypes.string.isRequired, price: React.PropTypes.number.isRequired, initialQty: React.PropTypes.number }; static defaultProps = { title: "Undefined Product", price: 100, initialQty: 0 }; componentWillMount() { this.recalculateTotal(); } increaseQty() { this.setState({qty: this.state.qty + 1}, this.recalculateTotal); } decreaseQty() { let newQty = this.state.qty > 0 ? this.state.qty - 1 : 0; this.setState({qty: newQty}, this.recalculateTotal); } recalculateTotal() { this.setState({total: this.state.qty * this.props.price}); } render() { return (結論) } } Quantity: {this.state.qty}
Price per item: ${this.props.price}
Total: ${this.state.total}
在這一節中,我們熟練掌握了ES6和ES7 React組建屬性的初始化,類型綁定。
下一小結,我們繼續研究React+ES6系列教程。
參考文檔Props vs state in React
About Prop Validation and more, official React documentation
About experimental features in BabelJS
ES7 Class Properties Proposal
掃碼申請加入全棧部落 |
---|
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/83983.html
摘要:使用箭頭函數和構造函數當方法被調用時,會保留上下文。我們能使用這個特征用下面的方法在構造函數中重定義函數。在調用方法的方使用函數綁定語法你也可以直接在非構造函數里面的里面直接使用函數綁定。 這是React和ECMAScript6/ECMAScript7結合使用系列文章的第三篇。 下面是所有系列文章章節的鏈接: React 、 ES6 - 介紹(第一部分) React類、ES7屬性初始...
摘要:在的組建創建中,不太可能使用混合機制。在中,這個組建將被命名為。他們中的其中一個如下結論高階組建功能強大和極具表現力。現在高階組建廣泛的被使用來替代老式的句法。 這是React和ECMAScript6/ECMAScript7結合使用系列文章的第四篇。 下面是所有系列文章章節的鏈接: React 、 ES6 - 介紹(第一部分) React類、ES7屬性初始化(第二部分) React類...
摘要:下一步我們將結果輸出到文件。這是我們用編寫的第一個非常簡單的組建。使用將創建的組建導出以便在其它地方能夠正常導入使用。 這是React和ECMAScript6結合使用系列文章的第一篇。 本文出自從零到壹全棧部落 下面是所有系列文章章節的鏈接: React 、 ES6 - 介紹(第一部分) React類、ES7屬性初始化(第二部分) React類,方法綁定(第三部分) ES6中Reac...
摘要:第二部分源碼解析接下是應用多個第二部分對于一個方法應用了多個,比如會編譯為在第二部分的源碼中,執行了和操作,由此我們也可以發現,如果同一個方法有多個裝飾器,會由內向外執行。有了裝飾器,就可以改寫上面的代碼。 Decorator 裝飾器主要用于: 裝飾類 裝飾方法或屬性 裝飾類 @annotation class MyClass { } function annotation(ta...
摘要:讓為生產研發的使用準備相關文件變得更容易。在這篇文章中,我們將重新創建和之前一樣的新的項目,但是我們使用。讓我們安裝其它我們將要使用的依賴包在這里我們沒有使用或者前綴,因為有常用包的注冊表。 這是React和JSPM結合使用系列文章的第五篇。 下面是所有系列文章章節的鏈接: React 、 ES6 - 介紹(第一部分) React類、ES7屬性初始化(第二部分) React類,方法綁...
閱讀 2805·2019-08-30 15:55
閱讀 2853·2019-08-30 15:53
閱讀 2289·2019-08-26 13:47
閱讀 2551·2019-08-26 13:43
閱讀 3153·2019-08-26 13:33
閱讀 2794·2019-08-26 11:53
閱讀 1789·2019-08-23 18:35
閱讀 795·2019-08-23 17:16