摘要:瀏覽器看效果效果顯示效果就是瞎比比我不聽瞎比比解析后的文本直接被顯示在頁面上,并沒有被瀏覽器解析,這是為了防止被攻擊而作的保護措施。
新搭建的個人博客,本文地址:React學習筆記2:React官方CommentBox實踐
所有的操作是繼續(xù)上一個學習筆記,參考的是React官方的CommentBox,不過不是100%按照其實現(xiàn)。
參考:https://facebook.github.io/re...
1、首先創(chuàng)建相關的文件
touch src/comment.js
2、修改webpack配置,一處是告訴webpack預處理的實體增加comment.js,另外一個是告訴webpack輸出的時候按照文件名字編譯輸出,而不是將所有js文件編譯到bundle.js,[name]實際上是entry數(shù)組中的key,通過修改key可以歸類目錄,例如"comment/index":./src/index.js,"comment/index":"./src/comment.js"會將編譯后的文件放到comment目錄下,通過這些配置可以更好的組織代碼結構
entry:{ "index":"./src/index.js", "comment":"./src/comment.js" }, output: { path: path.resolve(__dirname, "build"), filename: "[name].js" },
3、修改"build/index.html"引入文件修改為comment.js,重新運行webpack-dev-server,開始修改comment.js
4、分拆Comment組件,梳理出如下結構,在React中所有的東西都是以組件的形式存在
- CommentBox - CommentList - Comment - CommentForm
5、創(chuàng)建CommentBox組件,return()中的類html內容,在react中叫做JSX語法,其本身符合XML語法,react在編譯后會轉化為相應的js文件,官方介紹https://facebook.github.io/re...
之后可以去瀏覽器中看下效果
var CommentBox = React.createClass({ render:function(){ return (Hello world! I am a comment box.) } }); //渲染組件,注意修改index.html中div的id為content ReactDOM.render(,document.getElementById("content") );
6、創(chuàng)建CommentList、CommentForm組件
var CommentList = React.createClass({ render:function(){ return (Hello, I am a comment list!) } }); var CommentForm = React.createClass({ render:function(){ return (hi, I am a comment form.) } });
7、修改CommentBox代碼,引入CommentList、CommentForm組件。下面代碼中混合了HTML和組件代碼,JSX編譯器會自動將HTML代碼用React.createElement(tagName)去轉換。瀏覽器看下效果。
var CommentBox = React.createClass({ render:function(){ return () } });Comments
8、創(chuàng)建Comment組件,里面有{this.props.author}和{this.props.children}兩個變量,稱之為組件的屬性。修改CommentList組件,可以看到我們傳遞了author屬性。children是React預置屬性,指向組件內嵌的內容。返回瀏覽器查看修改變化。
var Comment = React.createClass({ render:function(){ return () } }) //修改CommentList組件,讓其載入Comment組件 var CommentList = React.createClass({ render:function(){ return ({this.props.author}
{this.props.children}) } });就是瞎比比 我不聽瞎比比
9、添加Markdown支持
//安裝依賴包 npm install marked --save //引入marked包 var marked = require("marked") //修改Comment組件,利用marked組件解析評論內容,轉為富文本格式。使用toString()是為了明確傳送給marked的為字符串格式。瀏覽器看效果效果 var Comment = React.createClass({ render:function(){ return () } }){this.props.author}
{marked(this.props.children.toString())}
//顯示效果 Comments stone就是瞎比比
mpanda我不聽瞎比比
hi, I am a comment form.
10、解析后的文本直接被顯示在頁面上,并沒有被瀏覽器解析,這是react為了防止被XSS攻擊而作的保護措施。React提供了一個并不友好的特殊API保證能夠實現(xiàn)在瀏覽器顯示原始HTML
var Comment = React.createClass({ rawMarkup:function(){ var rawMarkup = marked(this.props.children.toString(),{sanitize:true}) return {__html:rawMarkup} }, render:function(){ return () } }){this.props.author}
JSX中dangerouslySetInnerHTML屬性必須在接收到一個對象參數(shù),且對象參數(shù)中明確使用__html作為key時,才會將其內容作為原始HTML插入頁面中,而且不建議直接在
直接這樣完成書寫,目的就是明確提醒開發(fā)者,這里是有風險的,您是絕對的信任這段插入的內容。再次查看瀏覽器效果。It works!var data = [ {"id":1,"author":"stone","text":"換一個位置瞎比比"}, {"id":2,"author":"mpanda","text":"不喜歡你瞎比比"}, ] //傳遞數(shù)據到CommentBox ReactDOM.render(,document.getElementById("content") ); //直接傳遞數(shù)據到CommentList var CommentBox = React.createClass({ render:function(){ return ( ) } }); //在CommentList重新完成組件的組裝,刷新瀏覽器看效果 var CommentList = React.createClass({ render:function(){ var commentNodes = this.props.data.map(function(comment){ return (Comments
{comment.text} ) }); return ({commentNodes}) } });
12、從組件封裝來說我們已經封裝了一個很不錯的組件,只需要傳遞相關json數(shù)據到CommentBox即可。不過所有的數(shù)據都是在組件創(chuàng)建的時候,利用不可變量參數(shù)props一次性傳遞給組件。state同樣為組件的私有變量,可以通過this.setState()來設置變量的值,每次設置變量的值,組件都會重新渲染一遍自己。利用state修改我們的程序,讓其動態(tài)渲染頁面。
//為了方便進行ajax請求,引入jquery,當然完全可以不引入 var $ = require("jquery") var CommentBox = React.createClass({ //getInitialState函數(shù)在組件的整個生命周期只會執(zhí)行一次,我們在里面初始化數(shù)據 getInitialState:function(){ return {data:[]} }, //componentDidMount函數(shù)同樣是有React自動調用,時間是在組件第一渲染完畢后。當然因為data在初始化的時候數(shù)據為空,實際上這時候渲染的組件沒有內容。 componentDidMount:function(){ $.ajax({ url:this.props.url, //因我本地server是php,且跨域,所以我們使用jsonp解決跨域問題,具體jsonp實現(xiàn),請自行google dataType:"jsonp", cache:false, jsonp:"callback", jsonpCallback:"getComment", success:function(data){ //獲取到數(shù)據后,通過setState設置數(shù)據,組件會自動再次渲染 this.setState({"data":data}) }.bind(this), error:function(xhr,status,err){ console.log(this.props.url,status,err.toString()) }.bind(this) }) }, render:function(){ return () } }); //將URL地址傳遞個組件 ReactDOM.render(Comments
,document.getElementById("content") );
13、我們在瀏覽器看效果的時候因為數(shù)據請求都是在毫秒級別完成不方便看到重新渲染的效果,我們引入一個定時器。刷新瀏覽器,哈哈,2s后自動載入了評論數(shù)據。
var CommentBox = React.createClass({ getInitialState:function(){ return {data:[]} }, loadCommentsFromServer:function(){ $.ajax({ url:this.props.url, dataType:"jsonp", cache:false, jsonp:"callback", jsonpCallback:"getComment", success:function(data){ this.setState({"data":data}) }.bind(this), error:function(xhr,status,err){ console.log(this.props.url,status,err.toString()) }.bind(this) }) }, componentDidMount:function(){ setInterval(this.loadCommentsFromServer,2000) }, render:function(){ return () } });Comments
14、官方教程中評論提交分兩種完成。第一種完成了提交完成后,需要刷新,再次從服務器獲取評論數(shù)據,第二種提交評論后直接把提交的數(shù)據附加到評論后面,利用setState重新渲染頁面。顯然第二種體驗更好,直接實現(xiàn)第二種。
先做分析,在CommentForm組件中,如果完成數(shù)據的提交,那么需要重新設置CommentList中的數(shù)據,但是CommentList的數(shù)據又是CommentBox傳遞過去的,那么提交數(shù)據的操作不如直接在CommentBox中完成,然后利用setState重新設置CommentList的數(shù)據,CommentList完成自動刷新。
//之前獲取評論接口利用的是jsonp,但是提交評論必須post方法,所以jsonp無法完成,但是有不能通過跨域操作。webpack支持proxy(代理)模式,可以把一部分接口直接轉發(fā)到后端,修改webpack配置,請自行替換后端服務。 devServer:{ contentBase:"./build", proxy:{ "/api/*":{ target:"http://***.local.com:80", host:"***.local.com", secure: false, }, bypass: function(req, res, proxyOptions) { if (req.headers.accept.indexOf("html") !== -1) { console.log("Skipping proxy for browser request."); return "/index.html"; } }, } }
//注意傳遞的url,會自動轉發(fā)到http://***.local.com:80/api/comment ReactDOM.render(,document.getElementById("content") );
var CommentBox = React.createClass({ //增加評論提交方法,后臺服務 handleSubmitComment:function(data){ $.ajax({ //請注意,后臺接口我把評論和獲取評論放到了一起,只是提交方式不一樣,一個是get,一個是post url:this.props.url, type:"POST", data:data, dataType:"json", cache:false, success:function(data){ //測試接口直接返回了我提交的內容,所以可以直接附加數(shù)據,讓CommentList自動刷新 this.setState({data:this.state.data.concat(data)}); }.bind(this), error:function(xhr,status,err){ console.log(this.props.url,status,err.toString()) }.bind(this) }) }, render:function(){ return () } });) } }); var CommentForm = React.createClass({ getInitialState:function() { return {author:"",text:""} }, //完成數(shù)據的綁定,通過setState也能保證跟此數(shù)據相關的UI完成重新的渲染 handleAuthorChange:function(event){ this.setState({author:event.target.value}) }, handleTextChange:function(event){ this.setState({text:event.target.value}) }, handleSubmit:function(event){ //組織表單默認的submit提交 event.preventDefault(); var author = this.state.author.trim() var text = this.state.text.trim() if(!text||!author) { return; } //調用CommentBox上的評論提交方法 this.props.onSubmitComment({author:author,text:text}); this.setState({author:"",text:""}) }, render:function(){ return (Comments
//將評論提交接口傳遞個CommentForm組件
到此整個示例聯(lián)系完成!之后要完成用es6語法重構該項目。
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉載請注明本文地址:http://www.ezyhdfw.cn/yun/78554.html
摘要:新搭建的個人博客,本文地址學習筆記用重寫在一開始的時候配置中我們就加入了的支持,就是下面的配置,但之前的學習筆記都使用的完成,所以專門作一篇筆記,記錄使用完成創(chuàng)建相關文件修改,增加該入口文件修改,引入該文件做個簡單的測試,看下瀏覽器全部用來 新搭建的個人博客,本文地址:React學習筆記3:用es2015(ES6)重寫CommentBox在一開始的時候webpack配置中我們就加入了e...
摘要:例子全解析近些時間一直在關注,關于如何學習可以參照鏈接的文章自行制定計劃。千里之行,始于足下。此外,輸出的內容要解析為,而在默認情況下,基于預防攻擊的考慮,對輸出的內容是不解析為的。 React-tutorial例子全解析 Talk is cheap,Show me the code 近些時間一直在關注React,關于如何學習React可以參照鏈接的文章自行制定計劃。千里之行,始于足下...
摘要:組件通信實現(xiàn)表單提交昨晚做了一個的例子,主要實現(xiàn)的是提交表單實現(xiàn)評論的功能,在做之前先簡單介紹一下。并稱為前端大框架,就目前來看,盡管發(fā)布了也在今年月份發(fā)布了,更不在話下,大家要是想學習的話可以去官網學習。 react組件通信實現(xiàn)表單提交 昨晚做了一個react的例子,主要實現(xiàn)的是提交表單實現(xiàn)評論的功能,在做之前先簡單介紹一下React。 showImg(https://segment...
摘要:作者滬江前端開發(fā)工程師本文原創(chuàng)翻譯,有不當?shù)牡胤綒g迎指出。管理數(shù)據,而提供服務器上的數(shù)據,因此應用于處理網絡請求。結論使用建立的應用都是模塊化的會成為其中一個模塊,庫是另一個模塊。原文原創(chuàng)新書移動前端高效開發(fā)實戰(zhàn)已在亞馬遜京東當當開售。 作者:Oral (滬江Web前端開發(fā)工程師)本文原創(chuàng)翻譯,有不當?shù)牡胤綒g迎指出。轉載請指明出處。 當你問起有關AJAX與React時,老司機們首先就會...
閱讀 4100·2021-09-23 11:51
閱讀 3213·2021-09-22 15:59
閱讀 1083·2021-09-09 11:37
閱讀 2246·2021-09-08 09:45
閱讀 1416·2019-08-30 15:54
閱讀 2229·2019-08-30 15:53
閱讀 622·2019-08-29 12:12
閱讀 3437·2019-08-29 11:15