翻譯自這裏:https://engineering.hexacta.c...javascript
上一節咱們介紹了Didact Elements,使用了一種很麻煩的方法來表明要渲染的DOM。這一節咱們將介紹如何使用JSX來建立Didact Elements。java
下面是一個Didact Elements的原生對象表示:node
const element = { type: "div", props: { id: "container", children: [ { type: "input", props: { value: "foo", type: "text" } }, { type: "a", props: { href: "/bar", children: [{ type: "TEXT_ELEMENT", props: { nodeValue: "bar" } }] } }, { type: "span", props: { onClick: e => alert("Hi"), children: [{ type: "TEXT_ELEMENT", props: { nodeValue: "click me" } }] } } ] } };
有了JSX這個語法糖以後咱們就可使用下面這個方法來建立和上面同樣的元素:git
const element = ( <div id="container"> <input value="foo" type="text" /> <a href="/bar">bar</a> <span onClick={e => alert("Hi")}>click me</span> </div> );
若是你對JSX不熟悉你能夠能會想上面這段代碼是個無效的JS對象-----沒錯,你想的是對的。爲了讓瀏覽器能解析JSX,咱們須要使用預處理器(好比babel,想對JSX有更多瞭解的能夠看這裏)來將JSX轉換一下。例如babel會將上面的JSX轉成下面這個樣子:github
const element = createElement( "div", { id: "container" }, createElement("input", { value: "foo", type: "text" }), createElement( "a", { href: "/bar" }, "bar" ), createElement( "span", { onClick: e => alert("Hi") }, "click me" ) );
剩下咱們要作的就是添加一個createElement
方法來讓Didact支持JSX,其餘的工做就能夠交給預處理器了。createElement
方法的第一個參數是元素的類型type
,第二個參數是元素的props對象,剩下的其餘參數就是children
了。createElement
方法會返回帶有type
屬性和props
屬性的對象,props
屬性值也是一個對象,該對象含有第二個參數的全部屬性,第二個參數以後的其餘參數會放在一個數組中,並做爲該對象的children
屬性值。來實現一下createElement
方法:算法
function createElement(type, config, ...args){ const props = Object.assign({}, config); const hasChildren = args.length > 0; props.children = hasChildren ? [].concat(...args) : []; return {type, props} }
上面的createElement
在不碰到文本元素時都能很好的工做。遇到文本元素時,文本內容會以字符串形式在第二個參數以後傳遞給createElement
。又由於咱們以前定義了文本元素也須要有type
和props
屬性,因此咱們會將剛傳進來的字符串轉成一個文本元素。數組
const TEXT_ELEMENT = 'TEXT_ELEMENT'; function createElement(type, config, ...args){ const props = Object.assign({}, config); const hasChildren = args.length > 0; const rawChildren = hasChildren ? [].concat(...args) : []; props.children = rawChildren.filter(c => c != null && c !== false) .map(c => c instanceof Object ? c : createTextElement(c)); return { type, props }; } function createTextElement(value){ return createElement(TEXT_ELEMENT, { nodeValue: value}); }
上面代碼排除了子元素爲null
, undefined
和false
的狀況。這些狀況都是不必渲染的,因此也不須要添加到props.children
上。瀏覽器
這一節咱們依然沒有添加主功能到Didact上,但如今咱們已經開始使用JSX來建立元素了,這大幅提高了開發體驗。我已經將上節和本節的代碼在codepen上更新了。代碼頭部的註釋/** @jsx crerateElement8/
告訴了babel去使用createElement
來轉義JSX。babel
你也能夠在這裏查看代碼。dom
下一節咱們將往Didact中加入虛擬DOM和用來支持更新操做的一致性校驗算法。