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() {// 排除不要的 propsconst { 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.Geturl='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>);}}
