React--JSX

JSX是什么

实际上, JSX 仅仅只是 React.createElement(component, props, …children) 函数的语法糖

JSX能够提供给我们在JavaScript代码中编写HTML标签的能力

这样做的好处:

  • HTML代码片段可以当做变量任意地进行赋值、传递和计算等操作,在使用上更加地灵活;
  • 使得结构(视图层HTML)与行为(逻辑层JS)相统一,都在同一个文件、函数中处理,编写、维护和复用更加地方便和高效

以上仅个人见解

如下的代码:

function hello() {
  return <h1 className="title" title="hello">Hello world</h1>
}

会被编译为:

function hello() {
  return React.createElement("h1", {
    className: "title",
    title: "hello"
  }, "Hello world");
}

尝试其他JSX转换类型,可以在线Babel测试

React.createElement

  • 参数1 - 指定生成的标签名称
  • 参数2 - 对象,标签的属性
  • 参数3、4、5… - 子节点
function hello() {
  return 
  	<ul>
    <li>1</li>
    <li>1</li>
    <li>1</li>
  	</ul>
}

// 编译为
function hello() {
  return React.createElement(
  	"ul",
  	null,
  	React.createElement("li", null, "1"),
  	React.createElement("li", null, "1"),
  	React.createElement("li", null, "1")
  );
}

不需要太了解编译后的函数,写好JSX表达式就好了

指定React元素类型

确定是组件

JSX转换程序会将以小写字母开头的标签当做普通的HTML元素去创建,而大写字母开头的标签会当做组件处理,在作用域内寻找相应的变量,继而渲染、创建HTML元素

当返回一个普通的JSX HTML标签时,React.createElement会直接创建相应的标签

export default function Home() {
  return (
    <>
      <h1> {props.text} </h1>
    </>
  )
}

当返回一个组件的时候

  • 要确保该组件变量在作用域内
  • 函数组件:返回JSX表达式;类组件:具有render()方法
export default function Home() {
  return (
    <>
      <Hello text="Hello World" />
    </>
  )
}

或者:

function Hello (props) {
  return <h1> {props.text} </h1>
}

function WhoAmI (props) {
  return <h1> {props.name} </h1>
}

const MyComponents = {
  Hello,
  WhoAmI,
}
export default function Home() {
  return (
    <>
      <MyComponents.Hello text="Hello World" />
      <MyComponents.WhoAmI name="Lucy" />
    </>
  )
}

运行时确定组件

需要注意的是,JSX表达式的组件名称不能是一个属性计算表达式,像这样:

export default function Home() {
  return (
    <>
      // 错误!不能如此访问
      <MyComponents['Hello'] text="Hello World" />
    </>
  )
}

可以先使用一个变量接收,修改为如此:

export default function Home() {
  const Hello = MyComponents['Hello']
  return (
    <>
      <Hello  text="Hello World" />
    </>
  )
}

JSX属性传递

JSX属性传递有多重方式:

字面量。字符串基本数据类型,可以直接作为props传递,如:

<Hello text="Hello World" />

如果需要传递数字类型、Boolean类型这些基本类型,需要使用{ }包裹,以下方式是不对的

// 传递的 num 是字符串类型,isLogin 其实为 true
<MyComponents.Hello num="1" isLogin="false" />

正确的传递方式是:

<MyComponents.Hello num={1} isLogin={false} />

propstrue

对于undefinednullfalse0Boolean转换后都会计算为false,需要注意的是,当使用&&运算符计算渲染页面元素时,0仍然会执行渲染

{this.props.data.length && <h1>Hello World</h1>}

所以最好保证&&的左边是一个返回boolean类型的表达式

{this.props.data.length > 0 && <h1>Hello World</h1>}

JSX表达式作为子元素

可以使用任何JavaScript表达式作为JSX的子元素,例如:

export default function Home() {
  const num = 5
  const list = [1,2,3]
  const isLogin = true
  return (
    <>
      {num < 5 ? 'hello' : 'world'}
      {list.map(n => <li key={n}>{n}</li>)}
      {isLogin && <h1>Hello world</h1>}
    </>
  )
}

甚至可以使用一个函数作为JSX子元素,总之,是JavaScript表达式即可,函数作为JSX表达式如下例子所示:

function Repeat (props) {
  const items = []
  const textArr = ['hello', 'how old are you!', 'have a good time!']
  for (let i = 0, j = props.runTimes; i < j; i++) {
    items.push(props.children(textArr[i % 3], i))
  }
  return <>{items}</>
}


export default function Home() {
  return (
    <>
      <Repeat runTimes={10}>
        {(text, idx) => <h3 key={idx}>{text}</h3>}
      </Repeat>
    </>
  )
}

Repeat函数的作用是重复执行子元素(函数)的行为,重复次数由Repeat组件的runTimes属性决定,重复行为由父级组件中传递的子元素(函数)决定

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值