eact开发者的核心理念认为前端应该组件化,组件应该与关注点分离而不是与模板和展现逻辑分离。传统的前端组件化其思路都是基于模板技术,如Ext、jQuery UI等,结构化标记和生成结构化标记的代码是紧密关联的。此外,展现逻辑一般都很复杂,使用模板语言会使展现变得笨重。React解决这个问题的方式就是直接通过JavaScript代码生成HTML和组件树,这样,就可以使用JavaScript丰富的表达力去构建UI。但满屏的React.createElement出现的时候,代码的可读性、可维护性会变得极差。为了使这个过程变得更简单,React创建了类似XML的语法去构建虚拟DOM树,即JSX。
JSX即JavaScript XML,它使用XML标记的方式来创建虚拟DOM和声明组件。前面所举的例子,从本质上已经能完成所有的工作了。只是有一些开发效率问题,比如JavaScript代码与标签混写在一起、缺乏模板支持等。而使用JSX,则可以有效地解决这些问题。JSX的实质是使用一种更为“自然”的方式来创建ReactElement,它具有以下优点:可以使用熟悉的语法仿照HTML来定义虚拟DOM;JavaScript语义增强,提供更加语义化的标签支持复杂应用创建;程序代码更加直观;抽象ReactElement创建过程;支持变量嵌入和一些模板特性;便于代码模块化;与JavaScript之间存在等价转换。以Helloworld为例,使用JSX语法描述如下:
从上面的代码可以看出,JSX具有更简洁、更强大的表现力,而且基本不需要学习就能上手。需要说明的是,JSX是基于ECMAScript的一种新特性,但并不是一种新语言,它只是定义带属性的虚拟DOM树的一种语法,具体运行时,还需要通过转译器将JSX转换为原生JavaScript代码再执行。
React框架推荐使用的DOM语法格式为JSX语法,属于一种JavaScript扩展,React使用JSX来描述用户界面。我们可以粗略的认为JSX是JavaScript和HTML的结合,但是在实际的使用过程中还有一定的细节区别。本文就带领大家系统的学习JSX语法的格式。
const element=<div>你好,React!</div>;
这里需要注意,上述代码不是JavaScript字符串,所以没有用任何引号引住;也不是HTML代码。而是JSX语法格式。
React应用的最小单位是“元素”,JSX语法格式就是React推荐用来声明元素的。
对于相互嵌套的JSX元素,JSX语法推荐使用()扩住。
const ulElement=(
<ul>
<li>第一名</li>
<li>第二名</li>
</ul>
)
使用()扩住嵌套的JSX元素,让格式更加清晰。从实际的操作来看,不书写()也是可以的。
在JSX元素中使用变量必须使用{}扩住,变量可以用于JSX元素的内容中,也可以用于JSX元素的HTML属性取值上。
let name='张三';
const strongElement=<strong>你好,{name}</strong>
let url='https://www.baidu.com';
const link=<a href={url}>百度一下</a>
对于具有return返回值的函数,JSX元素可以像使用变量一样,利用{}扩住对函数进行调用。
function getSum(a,b){
return a+b;
}
let a=10,b=20;
const sum=<div>{a}+{b}={getSum(a,b)}</div>
上述几种情况中举的案例元素(element、ulEelement、strongElement、link、sum)都可以直接用在ReactDOM。render()方法的第一个参数中,充当向第二个参数所指的DOM节点中放入的元素。以sum为例,代码如下所示。
ReactDOM.render(
sum,
document.querySelector('#app')
);
JSX元素在书写时还要注意下列语法规定:
请大家仔细阅读下列代码:
const element=(
/*一个完整的JSX元素:本注释没有在任何标记内部,所以不用{}扩住*/
<div> {/*唯一的根节点:本注释在标记内部,必须用{}扩住*/}
<div className="top"> {/*className属性的使用*/}
{/*style属性的使用必须是双大括号*/}
<div style={{width:'1200px',height:'40px',backgroundColor:'#3385ff'}}>
欢迎学习React框架。
<img src=”images/01.jpg” /> {/*标记必须有结尾标识*/}
</div>
</div>
</div>
);
ReactDOM.render(
element,
document.querySelector('#app')
);
上述代码在浏览器中运行,可以从开发人员工具的Elements选项卡中看到下列如图所示的结构。
从图中可以看得出,id属性取值为app的div和class属性取值为top的div之间,有一个空的div。这是由于为了满足JSX元素必须具备一个唯一的根节点,而设置的最外层的div标记对。为了不让最外层的根节点显示在DOM结构中,React建议使用React.Fragment作为所有JSX元素最外层的根节点。代码改为如下格式。
const element=(
/*一个完整的JSX元素:本注释没有在任何标记内部,所以不用{}扩住*/
<React.Fragment> {/*唯一的根节点:本注释在标记内部,必须用{}扩住*/}
<div className="top"> {/*className属性的使用*/}
{/*style属性的使用必须是双大括号*/}
<div style={{width:'1200px',height:'40px',backgroundColor:'#3385ff'}}>
欢迎学习React框架。
<img src=”images/01.jpg” /> {/*标记必须有结尾标识*/}
</div>
</div>
</ React.Fragment >
);
这时再看开发人员工具的Elements选项卡,React.Fragment标记位置是没有任何标记对的。
在JSX格式中遍历数组不能使用for循环,只能使用ES5为数组提供的各种方法。下面的例子展示了用数组的map()方法来遍历数组的功能实现。
例1:实现页面导航条的JSX格式。
let navText=['首页','产品展示','技术展望','视频会议','金牌团队','关于我们'];
let navLink=['index.html','product.html','technology.html','videol.html','team.html','about.html'];
const nav=(
<React.Fragment>
<div className="top">
<div className="topContent">
<ul>
{
navText.map((item,index)=>{
return <li key={index}><a href={navLink[index]}>{item}</a></li>
})
}
</ul>
</div>
</div>
</React.Fragment>
);
从上述代码中可以看出下列有关JavaScript语言在JSX语法中的规范:
例2:有一个JSON数组,每个元素有两个属性:isShow和file。其中isShow取值为逻辑值,file取值为表示图片路径的字符串。当isShow取值为true时,file指定的图片要显示在页面中;当isShow取值为false时,file指定的图片不显示在页面中。
let picture=[
{isShow:true,file:'images/01.jpg'},
{isShow:true,file:'images/02.jpg'},
{isShow:false,file:'images/03.jpg'},
{isShow:true,file:'images/04.jpg'},
{isShow:true,file:'images/05.jpg'}
];
const img=(
<React.Fragment>
<h2>图片欣赏</h2>
<div className="picture">
{
picture.filter((item,index)=>{
return item.isShow
}).map((item,index)=>{
return <img src={item.file} key={index} />
})
}
</div>
</React.Fragment>
);
上述代码中,使用数组的filter()方法对picture数组进行筛选,筛选条件是isShow取值为true。然后再对筛选出来的数组元素使用map()方法进行遍历,以用来在页面中显示图片。
在JSX格式中是不能直接使用JavaScript的if语句的,我们通过下列五种方式来为大家讲解可行的方法。
例:设置一个变量flag。规定当flag=true时,页面中显示一个类名为box的div标记;当flag=false时,页面中显示一个类名为fox的div标记。
JavaScript提供的三元运算符(? :)也被称为“三目运算符”。该运算符适合分为两种情况的分支判定。
let flag=true;
const element=(
<React.Fragment>
{
flag?
<div className="box">
我是box元素......
</div>
:
<div className="fox">
我是fox元素
</div>
}
</React.Fragment>
);
JavaScript提供的逻辑与运算符(&&)的短路原理规定:当&&运算的左侧为false时,右侧不予计算。该运算符适合多分支的判定。
let flag=true;
const element=(
<React.Fragment>
{flag && <div className="box">
我是box元素......
</div>}
{!flag && <div className="fox">
我是fox元素
</div>}
</React.Fragment>
);
上述代码中,因为flag变量的取值为true,所以!flag的取值为false,则!flag &&右侧的元素不再计算,也就不会被渲染出来。
既然JSX格式不允许直接使用if语句,那我们就不在JSX格式中使用。我们可以在JSX格式以外的区域使用if语句。
let flag=false;
let target;
if(flag){
target=(
<div className="box">
我是box元素......
</div>
)
}else{
target=(
<div className="fox">
我是fox元素
</div>
)
}
const element=(
<React.Fragment>
{target}
</React.Fragment>
);
上述代码中定义了一个名为target的变量,通过在JSX格式以外进行if语句的判定,让target变量获得不同的JSX元素,最终在React.Fragment标记对中使用{target}引用了判定后的结果。
我们也可以在JSX格式以外的区域声明一个函数,在函数体总使用if语句进行判定,并最终将需要渲染的JSX格式利用return语句返回。
let flag=true;
function getTarget(){
if(flag){
return (
<div className="box">
我是box元素......
</div>
)
}else{
return (
<div className="fox">
我是fox元素
</div>
)
}
}
const element=(
<React.Fragment>
{getTarget()}
</React.Fragment>
);
上述代码中定义了一个名为getTarget的函数,该函数内部使用if判定flag变量的值,然后利用return语句将需要的JSX元素返回出去。在React.Fragment标记对中只需要使用{getTarget()}调用该函数即可。
本文是React系列教程的第二篇文章,主要为大家讲解了React框架中JSX语法的书写格式。系统的学会了JSX语法的书写格式,对于编写复杂的React项目有很大的帮助。明天会为大家系统的讲解React组件的使用方法。
小海前端,具有18年Web项目开发和前后台培训经验,在前端领域著有较为系统的培训教材,对Vue.js、微信小程序开发、uniApp、React等全栈开发领域都有较为深的造诣。入住?,希望能够更多的结识Web开发领域的同仁,将Web开发大力的进行普及。同时也愿意与大家进行深入的技术研讨和商业合作。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>jsx</title>
<style>
.title{
background-color: orange:
width: 200px;
}
</style><!--定义个样式,也可以写在CSS文件里,引入进来-->
</head>
<body>
<div id="test"></div>
<script type="text/javascript" src="../js/react.development.js"></script>
<script type="text/javascript" src="../js/react-dom.development.js"></script>
<script type="text/javascript" src="../js/babel.min.js"></script>
</body>
<script type="text/babel">
const myid="lOVE you"
const mydata="hellO jsx"
const VDOM=( // <!--h2标签引入样式,用className,span标签引入内联样式的时候,不是用双引号,而是双花括号,-->
<div>
<h2 className="title" id={myid.toLowerCase()}>
<span style={{color:'red',fontSize:'29px'}}>{mydata.toLowerCase()}</span>
</h2>)// <!--标签中混入JS表达式时要用花括号{},如这里mydata取值 -->
//jsx中只能有一个根标签,比如这里的h2,可以在h2的外面包一层div,就可以写两个h2
<h2 className="title" id={myid.toUpperCase()}>
<span style={{color:'red',fontSize:'29px'}}>{mydata.toLowerCase()}</span>
</h2>)
//标签首字母若是小写字母,则将该标签转为html中同名元素,若html中无该标签对应的同名元素,则报错
//标签首字母若是大写字母,react就去渲染对应的组件,若组件没有定义,则报错
</div>
ReactDOM.render(VDOM,document.getElementById('test'))
</script>
</html>
<script type="text/babel">
const data=['A','B','C']
const VDOM=(
<div> //js表达式会产生一个值。js语句(代码),有if,for,switch判断,
<h1>jsx框架</h1>
<ul>
{
data.map((item,index)=>{
return <li key={index}>{item}</li>
}) //item拿到data里面对应的值,map遍历的第二个值是索引值,
}
</ul>
</div>
)
ReactDOM.render(VDOM,document.getElementById('test'))
</script>
对应的网页如下:
模块是向外提供特定功能的js程序,一般就是一个js文件。
组件比模块更高一级,比如实现一个网页的头部的html,字体,css,js,图像这些元素组合在一起,就形成了头部这个组件。
函数式组件:
<script type="text/babel">
function MyComponent(){
return <h2>show the function component</h2>
}
ReactDOM.render(<MyComponent/>,document.getElementById('test'))
//<MyComponent/>要写上标签,函数定义首字母需要大写
</script>
执行了ReactDOM.render(<MyComponent/>。。之后,React解析组件标签,找到MyComponent组件,发现组件是使用函数定义的,随后调用该函数,将返回的虚拟DOM转为真是DOM,随后呈现在页面中。
类式组件:
*请认真填写需求信息,我们会在24小时内与您取得联系。