React – 初探
- 先道官網下載
- 解壓縮後放到你的本機伺服器環境,如 http://localhost,因為有些部分需要引用內部 .js 檔案,如果不是在伺服器環境,Chrome 會出現跨網域限制提示訊息
123XMLHttpRequest cannot load file:///C:/Users/580/Desktop/react/src/helloworld.js. Cross origin requests are only supported for protocol schemes: http, data, chrome, chrome-extension, https, chrome-extension-resource. - 關於 Hello World, 可參考。先在根目錄建立 helloworld.html ,並貼上
123456789101112131415161718<!DOCTYPE html><html><head><script src="build/react.js"></script><!-- 引用 react.js --><script src="build/JSXTransformer.js"></script> <!-- 因為 react.js 建議使用 jsx 的翻譯功能,來建構 Dom --></head><body><div id="example"></div><script type="text/jsx"> <!-- 注意這裡是使用 jsx ,所以需要經過 JSXTransformer.js 來建立 DOM 結構 -->React.render(<h1>Hello, world!</h1>, // 注意喔,因為是 jsx 所以不要使用 " 或 ' 來包圍document.getElementById('example'));</script></body></html>
這是內嵌的方法。 - 若要外嵌 React JSX 就需要這麼做。先在根目錄建立
src/helloworld.js 接著貼上
123456React.render(<h1>Hello, world!</h1>, // 注意這裡還是使用 XML 來建立 HTML 的結構喔document.getElementById('example'));
然後在你的 helloworld.html 添加參考
123<script type="text/jsx" src="src/helloworld.js"></script> <!-- 注意還是使用 jsx -->
透過上面步驟,就可以讓你簡單了解使用方式了,主要 React 建議使用 jsx 的方式來建構。下面我們看看這兩種方式的不同。原文參考
-
123456789101112131415var CommentBox = React.createClass({render: function() {return (<div className="commentBox">Hello, world! I am a CommentBox.</div>);}});React.render(<CommentBox />,document.getElementById('content'));
HTML 元素的名稱,可使用小寫,如同上面的 className=”commentBox” ;然而 React 自訂的 class 名稱,開頭務必要使用大寫,如上方的 CommentBox。可自行修改大小寫,就會發現問題了。 - 若將上面改成使用 JSX 語法,就這麼寫
12345678910111213141516var CommentBox = React.createClass({displayName: 'CommentBox',render: function() {return (// React.createElement(標籤, JSON格式的屬性, 標籤內容)React.createElement('div', {className: "commentBox"},"Hello, world! I am a CommentBox."));}});React.render(React.createElement(CommentBox, null),document.getElementById('content'));
– 上面的 var CommentBox 可以自定名稱。你可以改成如 obj ,這裡的開頭大小寫沒有限制。因為這只是變數,準備放到 React.createElement( 第一個參數這邊 ) 而已。
– 透過 React.createClass() 可以建立一個 React 組件。
– 最重要的方法 render ,是可以返回一個 React 的樹狀組件結構,最終會渲染到 HTML。
– 這裡的 div 標籤,並不是真正實際的 DOM 節點,而是 React 的一個元素。也就當作是個虛擬的吧!這是安全的,因為不是實際產生 HTML,所以可以避免XSS攻擊的問題。
– render 不可以返回基本的 HTML ,需要返回樹狀的組件結構。這就是為什麼要使用 React 的樹狀組件結構。這是非常關鍵的!
– 透過 React.render() 產生的根組件,會注入為原始的 DOM,作為二次使用時的立足點。– 我將上方改寫這樣來幫助了解變化。一樣他是先建立虛擬的 React 組件後,才注入到 HTML 。
123456789101112131415161718192021var obj = React.createClass({displayName: 'CommentBox',render: function (){return (React.createElement('a', {className: "commentBox", //記得是 classNamehref: 'http://facebook.com',title: '點擊我'},'我是超連結'));}});React.render(React.createElement(obj, null),document.getElementById('content'));這是使用 JSX 的格式來寫, React 推薦使用。關於 JSX 語法文章可參考這裡。
我們組合多個使用
建構組件 (Composing components) ,原文參考
先貼入你的 file.js
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 |
// 有個模組是 討論列表 var CommentList = React.createClass({ render: function() { return ( <div className="commentList"> Hello, world! I am a CommentList. </div> ); } }); // 有個模組是 討論表單 var CommentForm = React.createClass({ render: function() { return ( <div className="commentForm"> Hello, world! I am a CommentForm. </div> ); } }); // 有個模組是 討論方塊 // <CommentList /> 會對應上方的 CommentList // <CommentForm /> 會對應上方的 CommentForm // 最後被 <div class="commentBox"> 包圍起來 var CommentBox = React.createClass({ render: function() { return ( <div className="commentBox"> <h1>Comments</h1> <CommentList /> <CommentForm /> </div> ); } }); React.render( //需要的虛擬元件 React.createElement(CommentBox, null), //我們會在 id="content" 內渲染出結果 document.getElementById('content') ); |
使用 Markdown 與 for each 資料
helloworld.html
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
<!DOCTYPE html> <html> <head> <script src="build/react.js"></script> <script src="build/JSXTransformer.js"></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/marked/0.3.2/marked.min.js"></script> <!-- 使用套件 --> </head> <body> <div id="content"></div> <script type="text/jsx" src="src/helloworld.js"></script> </body> </html> |
helloworld.js
請按照順序看喔 0) -> 1) -> 2) ….
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 |
/** * 2) * render 中返回的結構建立了 <div className="commentBox"> ,它內部的 <CommentList> 會去對應變數 CommentList * 而且 <CommentList> 的屬性 data 也放置了我們由外部傳遞進來的參數 data 。我們又要把資料傳遞到 CommentList 。 * 而 <CommentForm /> 會去對應變數 CommentForm 。沒有參數的傳遞。 */ var CommentBox = React.createClass({ render: function() { return ( <div className="commentBox"> <h1>Comments</h1> <CommentList data={this.props.data} /> <CommentForm /> </div> ); } }); /** * 3-1) * 在這裡會去 each 我們 JSON 格式的資料 data 。 主要是透過 .map 的方法。 * this.props.data.map() 的回調涵式我們自訂叫做 comment 。這個 comment 就是 data 經過 each 的每個項目。 * * 可以看到 this.props.data.map() 會返回 <Comment> 結構。 * 而 <Comment> 有個叫做 author 的屬性,我們傳入 comment.author 。 * */ var CommentList = React.createClass({ render: function() { var commentNodes = this.props.data.map(function (comment) { return ( <Comment author={comment.author}> {comment.text} </Comment> ); }); // {commentNodes} 就會替換為上方定義的變數 commentNodes ,也就是批次的節點。 return ( <div className="commentList"> {commentNodes} </div> ); } }); /** * 4) * 這裡會返回 <div className="comment"> 結構。 * this.props.author 會取得 <Comment author={comment.author}> 中的 author 。 * */ var Comment = React.createClass({ render: function() { /** * 透過第三方套件 Markdown ,可以簡單格式化你的文字。 * 例如我們在 data 中看到的 *another* 用星號包圍文字,會被轉換為強調(使用<em>斜體)的HTML。 */ /** * 方法一、 * 如果只使用 {marked(this.props.children.toString())} 那在網頁就會看到 * "<p>This is <em>another</em> comment</p>" * * 但有個問題是,我們希望它是HTML編碼而不是要實體化的字元符號, * 之所以會看到實體化的字元,是因為 React 要避免造成 XSS 攻擊所做的保護。 * * 不過在這裡我們不需要使用,所以改成方法二的寫法。 */ // return ( // <div className="comment"> // <h2 className="commentAuthor"> // {this.props.author} // </h2> // {marked(this.props.children.toString())} // </div> // ); /** * 方法二、 * 藉由 marked 第二個變數來啟用消毒 {sanitize: true} 功能,這可以跳脫任何來源的 HTML 。 * 但要小心使用。 * * 這句特殊的API dangerouslySetInnerHTML={{__html: rawMarkup}} , * 是故意讓人難以插入 HTML (避免 XSS 攻擊),但我們要利用這個後門方法來正確執行 HTML 。 */ var rawMarkup = marked(this.props.children.toString(), {sanitize: false}); // console.log(rawMarkup) return ( <div className="comment"> <h2 className="commentAuthor"> {this.props.author} </h2> <span dangerouslySetInnerHTML={{__html: rawMarkup}} /> </div> ); } }); /** * 3-2) */ var CommentForm = React.createClass({ render: function() { return ( <div className="commentForm"> Hello, world! I am a CommentForm. </div> ); } }); /** * 0) * 先定義好JSON資料,後續我們將批次取出 * 這個通常位在伺服器端,不過我們這裡先直接寫在這裡。 */ var data = [ {author: "Pete Hunt", text: "This is one comment"}, {author: "Jordan Walke", text: "This is *another* comment"}, ]; /** * 1) * 第一個參數 <CommentBox data={data} /> 的意思,代表會自動對應變數 CommentBox ,並將 data 賦予到屬性 data 準備傳遞。 * 這代表我們要將 data 傳遞到 CommentBox 。 */ React.render( <CommentBox data={data} />, document.getElementById('content') ); |
改為遠端獲取 JSON 資料
修改這段就可以了。使用 url=’你的伺服器獲取網址’
1 2 3 4 5 6 |
React.render( <CommentBox url="comments.json" />, document.getElementById('content') ); |