使用JSX的注意事项

小程序的 wxml 只支持 viewtext 与它的那些内置组件标签,娜娜奇可以让你直接使用 div, span, p, b, strong 等 HTML 标签。块状元素会转换成 view, 内联元素会转换为 text

如果你使用 React 方式定义组件,那么对应的标签名必须以大写开头。

在小程序中,组件不支持包含其他标签,但我们的 React 组件可以充许包含其他标签或组件。

有关for循环,多重循环, if分支, 组件套组件 等用法,可以脚手架的 qunar 示例

为了兼容所有平台,我们定下这些规则

  • 原来打算使用view标签的地方,请使用div,h1这些块状元素代替
  • 文本必须包含在text, span, a, option, label这几种标签内
  • text标签下面不能出现text标签或span标签,span标签下面不能出现text标签或span标签
  • jsx中不能出现 声明变量或函数的语句,不能出现switch语句
  • 不要在标签内部使用纯空白或通过两边的空白撑开空间,即<div> </div<div> 111 </div,它们会变成 <div></div<div>111</div
  • 如果要支持快应用,类似<div><span>xxx</span></div>应该改成<div><text>xxx</text></div>,因为在快应用下span只能出现在text标签下,不能放在div下面。错误的用法
  1. <Login>
  2. <p>我是文本</p>
  3. </Login>

正确的用法

  1. <Login>
  2. <p><text>我是文本</text></p>
  3. <p><span>我是文本</span></p>
  4. </Login>

数据填充的使用

错误的用法

  1. <div aaa={this.title}>{this.data.content}</div>

正确的用法, 所有数据都只能来自this.props, this.state, this.context

  1. <div aaa={this.props.title}>{this.state.content}</div>

如果这是一个无状态组件,则这样用

  1. function AA(props, context){
  2. return <div aaa={props.title}>{context.content}</div>
  3. }

三元表达式的用法

错误的用法

  1. render() {
  2. return this.state.isOk ? null : <div>Home Page</div>;
  3. }

翻译出的XML会出现 null字样,因为{{null}} 会null +"" 变成"null"

  1. <block a:if="{{state.isOk}}">{{null}}</block><block a:else="true"><view>Home Page</view></block>

正确的用法

三元表达式与&&逻辑语句会转换为block标签,在快应用中,组件的根节点不能为block标签,因此需要包一层

  1. render() {
  2. return <div>{ this.state.isOk ? <div>Home Page</div>: null }<div>
  3. }

翻译出的XML体积还小这么多

  1. <div><block a:if="{{state.isOk}}"><view>Home Page</view></block></div>

JSX中不能出现if、switch语句或do表达式

错误的用法

  1. render() {
  2. return if( this.state.isOk ) {
  3. return <div>Home Page</div>
  4. } else{
  5. return "" //null会直接输出null,最好改成空字符串
  6. }
  7. }

do表达式也不允许

  1. // https://babeljs.io/docs/en/babel-plugin-proposal-do-expressions
  2. const Component = props =>
  3. <div className='myComponent'>
  4. {do {
  5. if(color === 'blue') { <BlueComponent/>; }
  6. else if(color === 'red') { <RedComponent/>; }
  7. else if(color === 'green') { <GreenComponent/>; }
  8. }}
  9. </div>

如果真的遇上这么复杂的分支判定,可以使用三元套三元

  1. // https://babeljs.io/docs/en/babel-plugin-proposal-do-expressions
  2. const Component = props =>
  3. <div className='myComponent'>
  4. { color === 'blue' <BlueComponent/> : (
  5. color === 'red' ? <RedComponent/> : (
  6. color === 'green' ? <GreenComponent/>: ""
  7. ))
  8. }
  9. </div>

事件绑定的使用

错误的用法

  1. <div onTap={this.props.fn}>点我</div>

正确的用法, 事件必须直接以this开头,来源于实例

  1. <div onTap={this.fn}>点我</div>

map方法必须将this往里面传递, map的第一个参数不要用箭头函数

  1. <ul>{
  2. this.state.list.map(function(el, index){
  3. return <li onClick={this.click1.bind(el, index)}>{el.name}</li>
  4. },this)
  5. }</ul>

render的使用

错误的用法

  1. class A extends React.Component{
  2. render(){
  3. var a = this.props
  4. return <div aaa={a.title}>{a.content}</div>
  5. }
  6. }

正确的用法

  1. class A extends React.Component{
  2. render(){
  3. return <div aaa={this.props.title}>{this.props.content}</div>
  4. }
  5. }

在早期的百度小程序中s-for指令不支持数组字面量,1.14.13已经修复

  1. class A extends React.Component{
  2. render(){
  3. return <div>{
  4. [111,222,333].map(function(el){
  5. return <p>{el}</p>
  6. })
  7. }</div>
  8. }
  9. }