學(xué)習(xí)React系列1-React-tutorial全解析_html/css_WEB-ITnose
Jun 24, 2016 am 11:16 AM
React-tutorial例子全解析
Talk is cheap,Show me the code
近些時(shí)間一直在關(guān)注React,關(guān)于 如何學(xué)習(xí)React可以參照鏈接的文章自行制定計(jì)劃。千里之行,始于足下。本文是React官方的教程上的一個(gè)例子,通過(guò)詳細(xì)地學(xué)習(xí),從中收獲不少,特此做了筆記,與大家共享交流進(jìn)步。
起步
-
下載 例子,然后進(jìn)行解壓
-
由于采用的node環(huán)境,因此下載解壓之后,只需在所在目錄運(yùn)行
npm installnode server.js
-
采用默認(rèn)端口設(shè)置,只需打開(kāi)瀏覽器,訪問(wèn) http://localhost:3000/
目錄結(jié)構(gòu)說(shuō)明
react-tutorial
--node_modules --body-parser:express中間件,用于接收和解析json數(shù)據(jù) --express:express框架--public --css --base.css:基本樣式文件 --scripts -- example.js:React應(yīng)用js文件 index.html:基本的HTML結(jié)構(gòu)--.editorconfig:用于在不同的編輯器中統(tǒng)一編輯風(fēng)格(文件編碼)的配置文件--.gitignore:git相關(guān)配置文件--app.json:web app的相關(guān)信息--comments.json:上傳的評(píng)論數(shù)據(jù)--LICENSE:項(xiàng)目代碼使用協(xié)議--package.json:項(xiàng)目所依賴的包,npm install的安裝包的配置文件--README.md:項(xiàng)目說(shuō)明書(shū),里面有使用說(shuō)明--requirements.txt:不清楚--server.js:服務(wù)器端的js代碼
App功能
此項(xiàng)目構(gòu)建了一個(gè)簡(jiǎn)單的應(yīng)用,如圖所示
服務(wù)器端
服務(wù)器端的功能還是相對(duì)簡(jiǎn)單的,通過(guò)代碼注釋的形式來(lái)分析
-
導(dǎo)入了依賴的模塊
var fs = require('fs'); //讀寫(xiě)文件var path = require('path'); //路徑var express = require('express'); //express框架var bodyParser = require('body-parser'); //中間件
-
生成app,并且進(jìn)行配置
//獲取comments.json文件的路徑var COMMENTS_FILE = path.join(__dirname, 'comments.json');//設(shè)置端口app.set('port', (process.env.PORT || 3000));//設(shè)置靜態(tài)文件的文件目錄路徑app.use('/', express.static(path.join(__dirname, 'public')));//啟用bodyParser中間件接收請(qǐng)求,并且接收并解析json數(shù)據(jù)app.use(bodyParser.json());app.use(bodyParser.urlencoded({extended: true}));
-
設(shè)置響應(yīng)頭部信息
app.use(function(req, res, next) { //允許跨域 CORS res.setHeader('Access-Control-Allow-Origin', '*'); //緩存設(shè)置 res.setHeader('Cache-Control', 'no-cache'); next();});
-
設(shè)置get請(qǐng)求url對(duì)應(yīng)的處理函數(shù)(獲取評(píng)論json數(shù)據(jù))
app.get('/api/comments', function(req, res) { //讀取comments.json文件,并且解析為json數(shù)據(jù) fs.readFile(COMMENTS_FILE, function(err, data) { if (err) { console.error(err); process.exit(1); } //讀取成功后,返回 res.json(JSON.parse(data)); });});
-
設(shè)置post請(qǐng)求url對(duì)應(yīng)的處理函數(shù)(提交評(píng)論數(shù)據(jù))
app.post('/api/comments', function(req, res) { //先讀取comments.json文件 fs.readFile(COMMENTS_FILE, function(err, data) { if (err) { console.error(err); process.exit(1); } //將文件內(nèi)容解析為json數(shù)據(jù) var comments = JSON.parse(data); //獲取新評(píng)論 var newComment = { id: Date.now(), author: req.body.author, text: req.body.text, }; //添加json數(shù)組中 comments.push(newComment); //將json數(shù)據(jù)寫(xiě)回到comments.json文件中,并且返回全部的評(píng)論數(shù)據(jù) fs.writeFile(COMMENTS_FILE, JSON.stringify(comments, null, 4), function(err) { if (err) { console.error(err); process.exit(1); } res.json(comments); }); });});
-
啟動(dòng),監(jiān)聽(tīng)端口
app.listen(app.get('port'), function() { console.log('Server started: http://localhost:' + app.get('port') + '/');});
web端
web端核心在于 example.js文件,結(jié)合官網(wǎng)的資料,我們對(duì)這個(gè)應(yīng)用進(jìn)行分析,學(xué)習(xí)如何構(gòu)建一個(gè)簡(jiǎn)單的react應(yīng)用。
組件結(jié)構(gòu)
React踐行了 Web Components的理念,依照組件化的開(kāi)發(fā)方式,我們來(lái)分析這個(gè)應(yīng)用的組件結(jié)構(gòu)(如圖所示):
即是:
-- CommentBox -- CommentList -- Comment -- CommentForm
組件之間的關(guān)系圖為:
組件Comment
如上述的結(jié)構(gòu)圖,我們從最底層開(kāi)始編寫(xiě)組件 Comment,這個(gè)組件需要做兩件事情
-
接收上層組件 CommentList傳遞的數(shù)據(jù),動(dòng)態(tài)渲染虛擬DOM節(jié)點(diǎn),則從 props中讀取數(shù)據(jù)
//評(píng)論人{(lán)this.props.author}//評(píng)論的內(nèi)容{this.props.children}
-
由于評(píng)論是支持MarkDown語(yǔ)法的,因此需要使用第三放庫(kù) marked對(duì)用戶輸入的內(nèi)容進(jìn)行處理。
var rawMarkup = marked(this.props.children.toString(), {sanitize: true});
-
此外,輸出的內(nèi)容要解析為HTML,而在默認(rèn)情況下,基于預(yù)防XSS攻擊的考慮,React對(duì)輸出的內(nèi)容是不解析為HTML的。此時(shí),需要利用到特殊的屬性 dangerouslySetInnerHTML,要將內(nèi)容放到一個(gè)對(duì)象的 _html屬性中,然后將這個(gè)對(duì)象賦值給 dangerouslySetInnerHTML屬性
var html = {_html:"輸出的html內(nèi)容"};<span dangerouslySetInnerHTML={html} />
var Comment = React.createClass({ rawMarkup : function() { var rawMarkup = marked(this.props.children.toString(),{sanitize:true}); return {_html : rawMarkup}; //React的規(guī)則,會(huì)讀取這個(gè)對(duì)象的_html內(nèi)容, }, render : function() { return ( <div className="comment"> <h2 className="commentAuthor"> {this.props.author} </h2> <span dangerouslySetInnerHTML={this.rawMarkup()} /> </div> ); }});
組件CommentList
組件 CommentList需要做的就是接收上一層組件 CommentBox傳遞過(guò)來(lái)的數(shù)據(jù),然后根據(jù)數(shù)據(jù)生成多個(gè)子組件 Comment
var CommentList = React.createClass({ render : function() { var commentNodes = this.props.data.map(function(comment){ return ( <Comment author={comment.author} key={comment.id}> {comment.text} </Comment> ); }); return ( <div className="commentList"> {commentNodes} </div> ); }})
在生成子組件 Comment時(shí),將每個(gè)子組件的key屬性設(shè)置為 comment.id,這是因?yàn)?key是一個(gè)可選的唯一標(biāo)識(shí)符,通過(guò)它可以給組件設(shè)置一個(gè)獨(dú)一無(wú)二的鍵,并確保它在一個(gè)渲染周期中保持一致,使得React能夠更加智能地決定應(yīng)該重用一個(gè)組件,還是銷毀并重新創(chuàng)建一個(gè)組件,進(jìn)而提升渲染性能。
組件CommentForm
組件 CommentForm需要做的就是兩件事情
-
管理自身的狀態(tài) this.state(即表單中輸入的評(píng)論人和評(píng)論內(nèi)容)
-
當(dāng)表單輸入發(fā)生變化時(shí)
-
當(dāng)表單提交時(shí)
-
-
當(dāng)submit事件觸發(fā)時(shí),調(diào)用上一層組件 CommentBox的事件處理函數(shù),改變組件 CommentBox的狀態(tài)。
var CommentForm = React.createClass({ getInitialState : function() { //設(shè)置初始狀態(tài), return {author:'',text:''}; }, handleAuthorChange : function(e) { this.setState({ author : e.target.value }); }, handleTextChange : function(e) { this.setState({ text : e.target.value }); }, handleSubmit : function(e) { e.preventDefault(); var author = this.state.author.trim(); var text = this.state.text.trim(); if(!text || !author){ //為空驗(yàn)證 return; } //觸發(fā)評(píng)論提交事件,改變父組件的狀態(tài) this.props.onCommentSubmit({author:author,text:text}); //改變自身的狀態(tài) this.setState({author:'',text:''}); }});
在這里有一個(gè)值得注意的點(diǎn),那就是抽象的自定義事件 commentSubmit和真實(shí)的事件 submit之間的聯(lián)系,這是一個(gè)相當(dāng)實(shí)用的技巧,在接下來(lái)的章節(jié)可以看到是如何實(shí)現(xiàn)的。
組件CommentBox
作為整個(gè)應(yīng)用的頂層組件, CommentBox需要做的事情有:
-
從服務(wù)器端請(qǐng)求已有的評(píng)論數(shù)據(jù)
-
將新的評(píng)論數(shù)據(jù)上傳到服務(wù)器
-
管理自身的狀態(tài),根據(jù)狀態(tài)對(duì)視圖進(jìn)行渲染(狀態(tài)改變的示意圖如下)
var CommentBox = React.createClass({ getInitialState : function(){ return {data : []}; }, loadCommentsFromServer : function() { //使用了jQuery的Ajax $.ajax({ url : this.props.url, dataType : 'json', cache : false, success : function(data) { this.setState({data:data}); }.bind(this), error : function(xhr,status,err){ console.err(this.props.url,status,err.toString()); }.bind(this) }); }, componentDidMount : function() { /* 這個(gè)方法屬于React組件生命周期方法,在render方法成功調(diào)用并且真實(shí)的DOM 已經(jīng)渲染之后,調(diào)用此方法,這個(gè)方法發(fā)送json數(shù)據(jù)請(qǐng)求,并且設(shè)置一個(gè)定時(shí)器 ,每隔一段時(shí)間就向服務(wù)器請(qǐng)求數(shù)據(jù) */ this.loadCommentsFromServer(); setInterval(this.loadCommentsFromServer,this.props.pollInterval); }, handleCommentSubmit : function(comment) { /* 這個(gè)方法也是比較有意思: 1. 自定義了一個(gè)commentSubmit事件,并且此方法作為該事件的處理函數(shù)。 2. 此方法是在子組件CommentForm的submit事件處理函數(shù)中調(diào)用 */ var comments = this.state.data; comment.id = Date.now(); var newComments = comments.concat([comment]); //改變自身狀態(tài) this.setState({data:newComments}); $.ajax({ url : this.props.url, dataType: 'json', type : 'POST', data : comment, success : function(data) { this.setState({data:data}); }.bind(this), error : function(xhr,status,err) { //還原數(shù)據(jù) this.setState({data:comments}); console.err(this.props.url,status,err.toString()); }.bind(this) }); }, render : function() { return ( <div className="commentBox"> <h1>Comments</h1> <CommentList data={this.state.data} /> <CommentForm onCommentSubmit={this.handleCommentSubmit} /> </div> ); }});
最后,只需將組件 CommentBox掛載到真實(shí)的DOM節(jié)點(diǎn)上,就可以看到效果了
ReactDOM.render( <CommentBox url="/api/comments" pollInterval={2000} />, document.getElementById('content'));

Hot AI Tools

Undress AI Tool
Undress images for free

Undresser.AI Undress
AI-powered app for creating realistic nude photos

AI Clothes Remover
Online AI tool for removing clothes from photos.

Clothoff.io
AI clothes remover

Video Face Swap
Swap faces in any video effortlessly with our completely free AI face swap tool!

Hot Article

Hot Tools

Notepad++7.3.1
Easy-to-use and free code editor

SublimeText3 Chinese version
Chinese version, very easy to use

Zend Studio 13.0.1
Powerful PHP integrated development environment

Dreamweaver CS6
Visual web development tools

SublimeText3 Mac version
God-level code editing software (SublimeText3)

Hot Topics

The key to keep up with HTML standards and best practices is to do it intentionally rather than follow it blindly. First, follow the summary or update logs of official sources such as WHATWG and W3C, understand new tags (such as) and attributes, and use them as references to solve difficult problems; second, subscribe to trusted web development newsletters and blogs, spend 10-15 minutes a week to browse updates, focus on actual use cases rather than just collecting articles; second, use developer tools and linters such as HTMLHint to optimize the code structure through instant feedback; finally, interact with the developer community, share experiences and learn other people's practical skills, so as to continuously improve HTML skills.

The reason for using tags is to improve the semantic structure and accessibility of web pages, make it easier for screen readers and search engines to understand page content, and allow users to quickly jump to core content. Here are the key points: 1. Each page should contain only one element; 2. It should not include content that is repeated across pages (such as sidebars or footers); 3. It can be used in conjunction with ARIA properties to enhance accessibility. Usually located after and before, it is used to wrap unique page content, such as articles, forms or product details, and should be avoided in, or in; to improve accessibility, aria-labeledby or aria-label can be used to clearly identify parts.

To create an HTML checkbox, use the type attribute to set the element of the checkbox. 1. The basic structure includes id, name and label tags to ensure that clicking text can switch options; 2. Multiple related check boxes should use the same name but different values, and wrap them with fieldset to improve accessibility; 3. Hide native controls when customizing styles and use CSS to design alternative elements while maintaining the complete functions; 4. Ensure availability, pair labels, support keyboard navigation, and avoid relying on only visual prompts. The above steps can help developers correctly implement checkbox components that have both functional and aesthetics.

To reduce the size of HTML files, you need to clean up redundant code, compress content, and optimize structure. 1. Delete unused tags, comments and extra blanks to reduce volume; 2. Move inline CSS and JavaScript to external files and merge multiple scripts or style blocks; 3. Simplify label syntax without affecting parsing, such as omitting optional closed tags or using short attributes; 4. After cleaning, enable server-side compression technologies such as Gzip or Brotli to further reduce the transmission volume. These steps can significantly improve page loading performance without sacrificing functionality.

To create a basic HTML document, you first need to understand its basic structure and write code in a standard format. 1. Use the declaration document type at the beginning; 2. Use the tag to wrap the entire content; 3. Include and two main parts in it, which are used to store metadata such as titles, style sheet links, etc., and include user-visible content such as titles, paragraphs, pictures and links; 4. Save the file in .html format and open the viewing effect in the browser; 5. Then you can gradually add more elements to enrich the page content. Follow these steps to quickly build a basic web page.

HTMLhasevolvedsignificantlysinceitscreationtomeetthegrowingdemandsofwebdevelopersandusers.Initiallyasimplemarkuplanguageforsharingdocuments,ithasundergonemajorupdates,includingHTML2.0,whichintroducedforms;HTML3.x,whichaddedvisualenhancementsandlayout

It is a semantic tag used in HTML5 to define the bottom of the page or content block, usually including copyright information, contact information or navigation links; it can be placed at the bottom of the page or nested in, etc. tags as the end of the block; when using it, you should pay attention to avoid repeated abuse and irrelevant content.

To embed videos in HTML, use tags and specify the video source and attributes. 1. Use src attributes or elements to define the video path and format; 2. Add basic attributes such as controls, width, height; 3. To be compatible with different browsers, you can list MP4, WebM, Ogg and other formats; 4. Use controls, autoplay, muted, loop, preload and other attributes to control the playback behavior; 5. Use CSS to realize responsive layout to ensure that it is adapted to different screens. Correct combination of structure and attributes can ensure good display and functional support of the video.
