JSX 本质
点击查看【codepen】
编译后的内容
class App extends React.Component {
render() {
return /*#__PURE__*/ React.createElement(
'div',
{ className: 'box', id: 'J_Box' } /*#__PURE__*/,
React.createElement(
'h1',
{ className: 'title' },
'This is a ' /*#__PURE__*/,
React.createElement('span', null, 'TITLE')
)
);
}
}
ReactDOM.render(
/*#__PURE__*/ React.createElement(App, null),
document.getElementById('app')
);
React.createElement(标签,{标签属性},…子元素)
JSX 其实是 React.createElement 函数调用的语法糖
React 会把 JSX 编译为 React.createElement 调用形式
React 元素类型
class MyButton extends React.Component{
render(){
return <button>Click</button>;
}
}
这个 MyButton 就是 React 元素,并且也是 React 元素类型
组件内使用 JSX,这个组件必须存在当前模块的作用域中
- 如在其它文件中,就使用 export / import 导出到使用的作用域
因为 React 编译 JSX 变为 React.createElement 调用形式,而要使用到 React 下的 createElement,那么要让 React 库存在当前的模块作用域中
- 在工程化时要
import React from 'react'
- 生产时是在 index.html 的 script 属性 src 来引用 React CDN
所以不需要import React
React 是持载至全局 window.React 能访问到如何在 JSX 中使用点语法
点击查看【codepen】JSX 书写规范
- 小写字母开头大代表 HTML 内置组件
<div>
<h1>
标签转换为 ‘div’ ‘h1’ 作为 React.createElement 第一个参数 - 大写字母开头代表自定义组件
<MyButton />
编译为React.createElement(MyButton)
运行时选择 React 类型
点击查看【codepen】JSX 的 props
表达式
JSX 中的大括号{}
里面可以传入任何 JavaScript 表达式if, for, switch, function 这些是语句,非表达式可以在 JSX 外面使用
class App extends React.Component {
state = {
mainTitle: "This is a MAINTITLE",
subTitle: "This is a SUBTITLE",
titleShow: "main"
};
render() {
// 非表达式在 JSX 外面使用
if (this.state.titleShow == "sub") {
title = <h2>{this.state.subTitle}</h2>;
} else {
title = <h1>{this.state.mainTitle}</h1>;
}
return <div>{title}</div>;
// 或者写在 JSX 里面传入 JS 表达式,使用三目运算符
return
(
<div>
{ titleShow === "sub" ? <h2>{subTitle}</h2> : <h1>{mainTitle}</h1> }
</div>
);
}
}
字面量字符串的注意
// 这是字符串字面量
<MyTitle title="这是一个标题" author="小野" />
// 这是表达式
<MyTitle title={"这是一个标题"} author={"小野"} />
JS表达式方式传入 props,HTML实体字符会被转义为普通字符
而字符串字面量传入 props 的方式不会对 HTML实体转义
<MyTitle title="这是一个<字符串字面量>" author={"<表达式>"} /> // => 这是一个<字符串字面量> <表达式>
<MyTitle title="这是一个<字符串字面量>" author={"<表达式>"} /> // => 这是一个<字符串字面量> <表达式>
props 的 bool 表达authorShow="true"
,这是字符串传入的意义是字符串的意思,不代表 Bool 真假,字符串 true 是逻辑真authorShow={true}
,Bool true 的意义代表 Bool 真假authorShow
, 不填值属性默认就是 Bool 真,但不推荐这么做因为语义不好
props 属性展开操作
class App extends React.Component {
render() {
// 排除不要的 props
const { abc, ...others } = this.props;
return (
<div>
{/* props 属性展开操作 */}
<MyTitle {...others} />
</div>
);
}
}
ReactDOM.render(
<App title="This is a TITLE" author="xiaoye" authorShow={true} abc={123} />,
document.getElementById("app")
);
JSX 子元素
注释{/* */}
字符串字面量 不转义
- 去掉首尾空格换行
- 字符串之间的多个空格压缩为一个空格 ( )
- 字符串之间的换行压缩为一个空格(
)
JSX 作为 JSX 的子元素
可以用数组返回多个元素
null, undefined, bool 都是可以作为 JSX 的子元素,这些子元素是会被忽略不会渲染,为解决条件渲染的问题
标签是会渲染
点击查看【codepen】
JSX 函数子元素
JSX 的 props.children 跟 props 本身是有一致的特性
props.children 可以传递任何类型的子元素
点击查看【codepen】
const Http = {
Get: class extends React.Component {
async componentDidMount() {
const result = await axios(this.props.url);
this.setState(
{
data: result.data,
},
() => {
this.setState({
component: this.props.children(this.state.data),
}, 1000);
}
);
}
state = {
data: [],
component: this.props.loading || 'Loading...',
};
render() {
return this.state.component;
}
},
};
class App extends React.Component {
render() {
return (
<table>
<thead>
<tr>
<th>ID</th>
<th>姓名</th>
<th>年级</th>
</tr>
</thead>
<tbody>
<Http.Get
url='http://localhost:8080/getStudents'
loading={
<tr>
<td colSpan='3'>正在加载中...</td>
</tr>
}
>
{(data) => {
return data.map((item) => (
<tr key={item.id}>
<td>{item.id}</td>
<td>{item.name}</td>
<td>{item.grade}</td>
</tr>
));
}}
</Http.Get>
</tbody>
</table>
);
}
}