JSX 基本概念 JSX 是 JavaScript XML 的简写,表示了在 JavaScript 中书写 XML 格式的代码。它是 React 的核心内容,它可以让我们在 React 中创建元素更加简单,更加直观,提高开发效率。
什么是JSX?JS 扩展语法,可以在 JS 中书写 XML 语法 JSX的优点? 演示 我们可以在 babel 的网站,在线测试 babeljs ,这个网站可以把 JSX 代码转换成 JS 代码
注意 :JSX 是 JavaScript 的语法扩展 ,它无法在浏览器中直接使用,在 create-react-app 脚手架中内置了 @babel/plugin-transform-react-jsx 插件来解析它,成为 JavaScript 的标准语法。
JSX 基本使用 导入 react-dom 使用 JSX 创建元素 使用 react-dom 渲染 1 2 3 4 5 6 7 8 9 10 11 12 13 14 import ReactDom from 'react-dom' ;const element = ( <div id="box" > <h1>JSX</h1> <ul> <li>tom</ li> <li>jack</li> <li>tony</ li> </ul> </ div>); ReactDom.render(element, document .getElementById('root' ));
上述代码运行成功,现在 React17x 可以不必导入React包,因为在 babel 转换的时候自动导入了创建 React 元素的依赖。但是如果你使用 React16x 那么你还需要手动导入 React ,如何验证?安装下低版本的 React 包即可。
总结
导入 react-dom 使用 JSX 创建元素 使用 react-dom 渲染元素 17x 版本的 React 不需要导入,如果将来遇见 低版本 是需要导入的。补充
vscode settings.json 加上 在 react 中使用 ement 语法提示创建标签1 2 3 "emmet.includeLanguages" : { "javascript" : "javascriptreact" }
JSX 的注意事项 使用细节 特殊属性写法 className htmlFor 没有内容的节点可以使用 单标签 必需有根节点,可以使用 <></> 幽灵标签,其实是 <React.Fragment></React.Fragment> 简写 如果 JSX 有换行,最好使用 () 包裹 代码示例 1 2 3 4 5 <div className="box" > <label htmlFor="ck" ></label > <input id="ck" type="checkbox" /> </div>
1 2 <span className="icon-edit" />
1 2 3 4 5 6 7 8 9 10 import React from 'react' ;import ReactDom from 'react-dom' ;const element = ( <React.Fragment> <div>header</div> <div>footer</ div> </React.Fragment> ); ReactDom.render(element, document.getElementById('root'));
1 2 3 4 5 6 7 8 9 import ReactDom from 'react-dom' ;const element = ( <> <div>header</div> <div>footer</ div> </> ); ReactDom.render(element, document.getElementById('root'));
1 2 3 4 5 6 7 const element = ( <> <div>header</div> <div>footer</ div> </> );
JSX 嵌入表达式 在JSX 中使用{ } 嵌入JS表达式,注意不能使用语句。
展示数据 进行运算 三元运算 使用函数 使用 JSX 使用注释 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 import React from 'react' ;import ReactDom from 'react-dom' ;const data = { name: 'tom' , age: 18 , }; const up = () => { return data.name.toUpperCase(); }; const list = ( <ul> <li>jack</li> <li>tony</ li> </ul> ); const element = ( <div> {/ * 1. 使用数据 注释推荐快键键(ctrl+/) */ } <div>姓名:{data.name}</div> <div>年龄:{data.age}</ div> {} <div>明年几岁:{data.age + 1 }</div> {/ * 3. 使用三元 */} <div>是否成年:{data.age > 16 ? '是' : '否'}</ div> {} <div>姓名大写:{up()}</div> {/ * 5. 使用JSX(jsx也是表达式) */} <div>朋友:{list}</ div> </div> ); ReactDom.render(element, document.getElementById('root'));
JSX 条件渲染 使用分支语句 if/else 完成条件渲染 使用 三元运算符 完成条件渲染 使用 逻辑运算符 完成条件渲染 if/else 条件渲染 1 2 3 4 5 6 7 8 9 10 11 12 const loading = true ;const getContent = () => { if (loading) { return <div > 正在加载...</div > ; } else { return <div > 数据加载完毕,这是显示数据</div > ; } }; const element = <div > {getContent()}</div > ;
三元运算符 完成条件渲染 1 2 3 4 5 6 7 const loading = true ; const element = ( <div> {loading ? <div > 正在加载...</div > : <div > 数据加载完毕,这是显示数据</div > } </div> );
逻辑运算 完成条件渲染 1 2 3 4 5 6 7 8 const loading = true ;const element = ( <div> {loading && <div > 正在加载...</div > } {loading || <div > 数据加载完毕,这是显示数据</div > } </div> );
JSX 列表渲染 可以渲染 JSX 数组 使用 map 渲染列表 直接在 JSX 中使用 map 渲染列表 key 属性使用可以渲染 JSX 数组 1 2 3 4 const list = [<li > tom</li > , <li>jack</li>, <li>tony</ li>];const elemet = <ul > {list}</ul > ;
使用 map 渲染列表 1 2 3 4 5 6 const list = ['tom' , 'jack' , 'tony' ];const list2 = list.map((item ) => <li>{item}</li>); / / 3. 使用 const element = <ul>{list2}</u l>;
直接在 JSX 中使用 map 渲染列表 1 2 3 4 5 6 7 8 9 10 const list = ['tom' , 'jack' , 'tony' ];const element = ( <ul> {list.map((item ) => ( <li>{item}</li> ))} </u l>);
key 属性使用 1 2 3 4 5 6 7 8 9 10 11 const list = ['tom' , 'jack' , 'tony' ];const element = ( <ul> {list.map((item ) => ( <li key={item}>{item}</li> ))} </u l>);
JSX 样式 - style 方式 style 接受一个采用小驼峰 命名属性的 JavaScript 对象,而不是 CSS 字符串style 中的 key 采用小驼峰 命名是为了与 JS 访问 DOM 节点的属性保持一致React 会自动添加 ”px” 后缀到内联样式为数字的属性后,其他单位需要手动添加演示代码
需求:去掉上一个列表案例 ul 的点,加上背景样式,设置字体大小,给第一个 p 设置两倍字体大小 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 import ReactDom from 'react-dom' const list = [ { id : 100 , name : 'tom' , age : 15 }, { id : 101 , name : 'jack' , age : 18 }, { id : 102 , name : 'tony' , age : 20 } ] + +const styleObject = { + listStyle: 'none' , + backgroundColor: 'pink' , + fontSize: 20 +} const element = (+ <ul style ={styleObject} > {list.map(item => { return ( <li key={item.id}> + <p style={{fontSize: '2em'}}>姓名:{item.name}</p> <p>是否成年:{item.age > 16 ? '是' : '否'}</p> </li > ) })} </ul > ) ReactDom.render(element, document .getElementById('root' ))
JSX 样式 - className 方式 在多数情况下,应使用 className 属性来引用外部 CSS 样式表中定义的 class
className 设置类名,和 class 属性要求一样只能是字符串如果需要根据数据设置类名,可以使用 { } 嵌入 JS 表达式实现 演示代码:
需求:在元素 button上根据 isActive 数据的值添加 active 类名 index.css 代码
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 .button { width : 100px ; height : 40px ; border : 1px solid #eee ; color : #999 ; border-radius : 4px ; display : inline-block; text-align : center; line-height : 40px ; box-shadow : 2px 2px 10px #ccc ; cursor : pointer; user-select : none; } .button .active { background : #069 ; color : #fff ; border-color : #069 ; } .button .block { display : block; width : 100% ; }
index.js 代码
1 2 3 4 5 6 7 8 9 10 11 import ReactDom from 'react-dom' ;import './index.css' ;const isActive = false ;const element = ( <span className={`button ${isActive ? 'active' : '' } ` }>按钮</span> ); ReactDom.render(element, document.getElementById('root'));
JSX 样式 - 动态 className 在使用 className 的时候遇见多个类名动态绑定,可以模仿 vue 使用对象的方式 vue 中绑定类名的时候使用 {类名:布尔} 用布尔值决定是否加上这个类名例如:在元素 button上根据 isActive 数据的值添加 active 类名,isBlock 数据的值添加 block 类名
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 import ReactDom from 'react-dom' ;import './index.css' ;const isActive = false ;const isBlock = false ;const classObject = { button: true , active: isActive, block: isBlock, }; const className = Object .keys(classObject) .filter((key ) => classObject[key]) .join(' ' ); const element = <span className ={className} > 按钮</span > ;ReactDom.render(element, document .getElementById('root' ));
JSX 样式 - classnames 库 使用 JS 原生的能力处理多个类名的动态绑定,当然这样的需求已经有 classnames 库给我们解决了。
安装导入 classnames 1 2 3 4 # 安装 npm i classnames # 或者 yarn add classnames
1 2 import classNames from 'classnames'
认识 classnames API 1 2 3 4 5 6 7 8 classNames('foo' , 'bar' ); classNames({ foo : true , bar : true }); classNames(['foo' , 'bar' ]); classNames('foo' , { bar : true });
例如还是上面那个需求:在元素 button上根据 isActive 数据的值添加 active 类名,isBlock 数据的值添加 block 类名
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 import ReactDom from 'react-dom' ;import classNames from 'classnames' ;import './index.css' ;const isActive = true ;const isBlock = true ;const className = classNames('button' , { active: isActive, block: isBlock, }); const element = <span className ={className} > 按钮</span > ;ReactDom.render(element, document .getElementById('root' ));