React – 初探
- 先道官網下載
- 解壓縮後放到你的本機伺服器環境,如 http://localhost,因為有些部分需要引用內部 .js 檔案,如果不是在伺服器環境,Chrome 會出現跨網域限制提示訊息
XMLHttpRequest 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 ,並貼上
<!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 接著貼上
React.render( <h1>Hello, world!</h1>, // 注意這裡還是使用 XML 來建立 HTML 的結構喔 document.getElementById('example') );
然後在你的 helloworld.html 添加參考
<script type="text/jsx" src="src/helloworld.js"></script> <!-- 注意還是使用 jsx -->
透過上面步驟,就可以讓你簡單了解使用方式了,主要 React 建議使用 jsx 的方式來建構。下面我們看看這兩種方式的不同。原文參考
-
var 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 語法,就這麼寫
var 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 。
var obj = React.createClass({ displayName: 'CommentBox', render: function (){ return ( React.createElement('a', { className: "commentBox", //記得是 className href: 'http://facebook.com', title: '點擊我' }, '我是超連結' ) ); } }); React.render( React.createElement(obj, null), document.getElementById('content') );
這是使用 JSX 的格式來寫, React 推薦使用。關於 JSX 語法文章可參考這裡。
我們組合多個使用
建構組件 (Composing components) ,原文參考
先貼入你的 file.js
// 有個模組是 討論列表 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
<!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) ….
/** * 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=’你的伺服器獲取網址’
React.render( <CommentBox url="comments.json" />, document.getElementById('content') );