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' ));