React 学习笔记(一):JSX


JSX:本质上来说,JSX只是React.createElement(component, prop, ...children) 方法的语法糖

<myHeader someData={data}>
  Header Content
</myHeader>

等价于:

React.createElement(
  'myHeader',        // Type
  {someData: data},  // props
  'Header Content'   // ...children
)

JSX的语法与原生html标签有一定相似性,不含有子节点的标签可以使用“自闭和”形式

<myHeader someData={data} />

它的...children参数就被设置为null,接下来我们逐个分析JSX语法里的各个元素

(一)JSX Type

Type:JSX语法的第一部分决定了React Element的类型

<MyElement />

大写的Type表明了它是一个React组件的引用,所以你必须保证(1)“MyElement”在作用域中;同时因为JSX会被编译成为React.Component(...)的形式,所以你还必须保证(2)React的library在作用域中

import React from 'react'        // React library
import MyElement from '...'      // MyElement Component

function doSth() {
  return <MyElement />
}

就像这样

其他值得注意的:

1.在JSX TYPE中使用“.”来指明React Component

const MyComponets = {
  Header: function Header(props) {
    return (<div>This is header</div>)
  }
  Footer: function Footer(props) {
    return (<div>This is footer</div>)
  }
}

function doSth() {
  return <MyComponents.Header />
}

2.请对自定义组件首字母大写

首字母小写的JSX Type代表着内置组件,如div, p, span,React会将它作为html标签

3.运行时选择Type

你不能使用表达式作为JSX的Type,但是可以将它的结果赋值给一个首字母大写的变量

function doSth(props) {
    return <MyComponents[props.Header] />    // Wrong!
}
functin doSth(props) {
  const Header = MyComponents[props.Header];    // True!
  return <Header />
}

(二)JSX props

JSX 的 props有多种指定的方式:

1.JavaScript Expression

就像:

<MyComponent myProp={1 + 2 / 1} />

注意:if 语句和 for循环并不是Expression,所以不能直接放在props中,但是可以放在JSX外达成相同的效果:

<MyComponent 
  myShow={if (flag === true) {return true;} else {return false;}}     // wrong!
  myList={for (item in list) {return doSth(item);}}    //wrong!
/>

正确的做法是:

for (item in list) {
  const show;
  const result;
  if (flag === true) {
    show = true;
  }
  result = doSth(result);
  return <MyComponent myShow={show} myList={result} />
}

2.字符串字面量

以下两种方式是等价的:

<MyComponent myString={'Hello'} />
<MyComponent myString="Hello" />

在字面量中,你甚至可以使用'<sth'的内容,他并不会引起标签未闭合的错误

3.使用默认值

指定一个prop的时候,如果不指定值,那他默认是 true。但是很不推荐这样做,因为在ES6的规范中,{foo}是{foo: foo}的简写形式,容易引起混淆

4.可扩展属性

可以将一个对象作为props传入JSX

function doSth() {
  return <MyComponent prop1={prop1value} prop2={prop2value} />
}
function doSth() {
  const myProps = {
    prop1: prop1value,
    prop2: prop2value
  }
  return <MyComponent {...myProps} /> 
}

以上两种用法是等价的

更进一步,可以将props解构成特定的props,并将其他的props放入可扩展属性中,如:

function Header = props => {
  const {title, ...other} = props;
  return <div {...other}>{ title }</div>;
}
总结起来,这种方式虽然使用方便,但是有可能吧不重要的属性也传入;并且可能传入不合法的属性;所以,请谨慎使用

(三)JSX Children

子元素是一个特殊的prop-props.children,位于JSX标签之中,它可以通过多种方法传入:

注意:这些方法都可以混合使用

1.字符串字面量:

<MyComponent>Hello</MyComponent>

JSX会自动去除多余的空行和空格

2.JSX Children

<MyComponent>
  <ChildComponent />
  <ChildComponent />
  <ChildComponent />
</MyComponent>

可以将其他JSX元素作为子元素

ReactComponent可以返回一个元素的数组

render() {
  return [
    <li>Child1</li>
    <li>Child2</li>
    <li>Child3</li>
  ]
}

3.JavaScript Expression

惯用法:渲染一个JSX表达式的列表

render() {
  return (
    <ul>{items.map(item => <li color={ item.color }>{ item.title }</li>)}</ul>
  )
}

4.函数

可以传入自定义组件的子元素可以是任意的,就像其他prop

// Calls the children callback numTimes to produce a repeated component
function Repeat(props) {
  let items = [];
  for (let i = 0; i < props.numTimes; i++) {
    items.push(props.children(i));    // 这里传入的i作为子元素(函数)的index参数
  }
  return <div>{items}</div>;
}

function ListOfTenThings() {
  return (
    <Repeat numTimes={10}>
      {(index) => <div key={index}>This is item {index} in the list</div>}
    </Repeat>
  );
}

很不常用,但是JSX可以做到!

5.Boolean, Null, undefined 会被忽视

它们不会被渲染

Tips:用于条件渲染

render() {
  return(
    <div>
     {isTrue && <MyComponent />}
    </div>
  )
}

请注意,0之类的“类错误”值并不会被忽视,请用 expressionCanBiggerThanZero > 0的表达式来替换0值,如:

render() {
  return(
    <div>
      { message.length > 0 && <MyComponents />}    // 直接使用message.length不会产生预期结果
    </div>
  )
}

另外,如果你想让false、true、null、undefined出现在输出中,请转换为字符串

render() {
  return(
    <div>
     { String(isTrue) }
    </div>
  )
}

猜你喜欢

转载自blog.csdn.net/u013637262/article/details/79994159