深入了解JSX
一:Why is JSX
各种编程语言层出不穷,每天都有新的编程语言出现,每隔一段时间,流行的编程语言将会如皇朝般更替。对于程序员来说,这是件又爱又恨的事情。语言的变化适应着科技的发展,不断优化旧的编程模式,使程序设计更加简单、合理。但目前看来这种变化过于迅速,使得程序员应接不暇,旧的语言还没有搞明白,新的语言又来了,更加令人无法沉下心来做事情,每个人想着不被技术淘汰,不被社会淘汰。尤其在中国,程序员成为当今社会最为焦虑的一种人,程序设计师成为一种青春饭的职业,以至于人人云,35岁要转管理,要转产品,要做CTO,我个人对此嗤之以鼻,去他妈的管理,去他妈的CTO,老子就想做个安静的程序员,微信公众号:react-javascript。
牢骚一顿,还是看看Facebook为什么要整出个JSX。JSX是一种扩展的JavaScript语法,类似于XML。官网上是这么描述的:我们认为组件化更好的方式不是要创建“模板”和“展示逻辑”,而是在自己内部将这些关系进行关联。另外,展示逻辑一般会比较复杂,使用模板去表示会更加臃肿。我们发现最好的解决方案是直接用JavaScript去直接生成这些组件的HTML和表示逻辑。但是JavaScript本身不具备这样的能力,因此就出现了JSX。
二.JSX不是必须的。
JSX并不是ReactJS必须的,如果你喜欢,完全可以不用采用JSX,而采用ReactJS的函数去创建HTML节点。如下:
React.createElement('a', {href: 'https://facebook.github.io/react/'}, 'Hello!')。
而采用JSX,则更加简单,清晰。如:
<a href="https://facebook.github.io/react/">Hello!</a>
如同在直接编写HTML标签,语法也基本相似,要比写ReactJS函数要方便的多。
三.组件中JSX的写法
1.节点写法与HTML类似
如:
var Nav;
// Input (JSX):
var app = <Nav color="blue" />;
其中要使用<Nav />, Nav必须在同一作用域内。
最终转化的Javascript是
var app = React.createElement(Nav, {color:"blue"});
2.组件的写法
如果要创建的组件有很多子节点,如form,可能有row,label,input等,不要采用以下方式:
// Awkward block of variable declarations
var Form = MyFormComponent;
var FormRow = Form.Row;
var FormLabel = Form.Label;
var FormInput = Form.Input;
var App = (
<Form>
<FormRow>
<FormLabel />
<FormInput />
</FormRow>
</Form>
);
而应该采用以下写法:
var Form = MyFormComponent;
var App = (
<Form>
<Form.Row>
<Form.Label />
<Form.Input />
</Form.Row>
</Form>
);
3.Javascript表达式
在JSX中Javascript的表达式采用({})而不是(“”)。
选择表达式如 :
var person = <Person name={window.isLoggedIn ? window.name : ''} />;
Boolea表达式如(两种表达式意义相同):
<input type="button" disabled />;
<input type="button" disabled={true} />
子节点表达式:
var content = <Container>{window.isLoggedIn ? <Nav /> : <Login />}</Container>;
说明的表达式:
<Nav>
{/* child comment, put {} around */}
<Person
/* multi
line
comment */
name={window.isLoggedIn ? window.name : ''} // end of line comment
/>
</Nav>
4.HTML元素写法
如(以下几种写法展示效果相同):
<div>First · Second</div>
<div>{'First · Second'}</div>
<div>{'First \u00b7 Second'}</div>
<div>{'First ' + String.fromCharCode(183) + ' Second'}</div>
但是不要写成<div>{'First & middot; Second'}</div>,否则将显示为First & middot; Second。
四.JSX与HTML的不同点。
JSX与HTML中基本写法相同,但也有不同之处,而在实际应用中恰恰是因为这些不同点成为编程过程中的坑。除了上一节中表达式的不同,JSX还有一些与HTML不同之处。
1.所有的DOM的属性应该采用驼峰命名法,类似于Java命名规则。只有data-*,aria-*等采用小写。
2.style属性采用JavaScript对象时也应采用驼峰命名而不是采用Css字符串,与JavaScript属于一致,会更有效,并且可以预防XSS安全漏洞。
3.Class,for已经成为JavaScript的保留字,因此以JSX创建DOM节点时,style class应采用className和htmlFor代替。如<div className=”foo”/>。
但是用户类元素还应直接采用class和for,如:<my-tag class="foo" />。
4.ReactJS中的事件变化较大,为了实现跨浏览器,优化性能,它采用了SynthecticEvent。希望在所有浏览器上保持一致。在写法上也采用驼峰命名。与HTML原有事件的基本对于关系是onclick对应于onClick。尤其是在v0.14之后,事件返回false将不再能阻止事件传播,需要采用e.stopPropagation()或者e.preventDefault()。(ReactJS的事件需细细分解了)。
5.Form 中input,textarea,select等于Html的用法区别较大。在ReactJS中分为Controlled Components 和UnControlled Components。
a.Controlled Components的写法
getInitialState: function() {
return {value: 'Hello!'};
},
handleChange: function(event) {
this.setState({value: event.target.value});
},
render: function() {
return (
<input
type="text"
value={this.state.value}
onChange={this.handleChange}
/>
);
}
Input值是通过state中的数据获取的,值的变化通过onChange事件改变state中的值。
如果采用以下写法,用户无法直接修改页面中input的值。render: function() {
return <input type="text" value="Hello!" />;
}
b.Uncontrolled Components的写法
如果<input>中没有value属性,则该组件是一个Uncontrolled Component。
可以通过defaultValue赋初始值,用户可以直接修改页面中input的值,修改的值会直接显示在页面上,并且可以通过onChange事件获得当前值。