下面先介绍一下jsx
JSX是一种JavaScript的语法扩展(extension),也在很多地方称之为JavaScript XML,因为看起就是一段XML语法;
它用于描述我们的UI界面,并且其完成可以和JavaScript融合在一起使用;
它不同于Vue中的模块语法,你不需要专门学习模块语法中的一些指令(比如v-for、v-if、v-else、v-bind);
jsx中的注释
jsx中的注释方法和js代码中和html中的注释方法不同
<div>
{/* 我是一段注释 */}
</div>
jsx中嵌入数据
当变量是Number、String、Array类型时,可以直接显示
当变量是null、undefined、Boolean类型时,内容为空
对象类型不能作为子元素
{/* 定义的数据 */}
this.state = {
name: "why", // String
age: 18, // Number
names: ["abc", "cba", "nba"], // Array
test1: null, // null
test2: undefined, // undefined
test3: true, // Boolean
friend: {
name: "kobe",
age: 40
}
}
{/* 使用定义的数据 */}
render() {
return (
<div>
{/* 正常显示 */}
<h2>{this.state.name}</h2>
<h2>{this.state.age}</h2>
<h2>{this.state.names}</h2>
{/* 不会显示 */}
<h2>{this.state.test1}</h2>
<h2>{this.state.test2}</h2>
<h2>{this.state.test3}</h2>
{/* 对象不能做jsx子类 */}
<h2>{this.state.friend}</h2>
</div>
)
}
}
jsx嵌入表达式
运算表达式
三元运算符
执行一个函数
render() {
const { firstname, lastname, isLogin } = this.state;
return (
<div>
{/*1.运算符表达式*/}
<h2>{ firstname + " " + lastname }</h2>
<h2>{20 * 50}</h2>
{/*2.三元表达式*/}
<h2>{ isLogin ? "登陆成功": "请先登录~" }</h2>
{/*3.进行函数调用*/}
<h2>{this.getFullName()}</h2>
</div>
)
}
jsx绑定属性
普通属性比如元素的title属性img的src属性a元素的href属性
绑定class属性
绑定内联样式style属性
render() {
const { title, imgUrl, link, active } = this.state;
return (
<div>
{/* 1.绑定普通属性 */}
<h2 title={title}>标题</h2>
<img src={imgUrl} alt=""/>
<a href={link} target="_blank">百度</a>
{/* 2.绑定class */}
<div className="box title">div元素</div>
<div className={"box title " + (active ? "active": "")}>div元素</div>
<label htmlFor=""></label>
{/* 3.绑定style */}
<div style={{color: "red", fontSize: "50px"}}>我是div,绑定style属性</div>
</div>
)
}
}
注意的是当给标签绑定类型class属性的时候和label标签中for属性 和js代码中的关键字ES6的class 以及for关键字冲突了,就改变成React所规定的写法className和htmlFor
jsx绑定事件和this的处理
我们需要通过{}传入一个事件处理函数,这个函数会在事件发生时被执行
render() {
return (
<div>
<button onClick={this.btnClick}>按钮1</button>
</div>
)
}
btnClick() {
{/* 使用已经定义好的数据 */}
console.log(this.state.message);
}
}
需要注意的是此时控制台会报错
原因是此时btnClick这个函数的this指向是undifined,React内部经过处理将this指向unidifined,在unidifined中取属性所以会报错
为了取到定义的数据我们要对其进行处理
render() {
return (
<div>
{/* 1.bind绑定this(显示绑定)到组件对象 */}
<button onClick={this.btnClick.bind(this)}>按钮1</button>
{/* 2.定义绑定的函数时, 使用箭头函数定义 */}
<button onClick={this.increment}>+1</button>
{/* 3.直接传入一个箭头函数, 在箭头函数中调用需要执行的函数*/}
<button onClick={() => { this.decrement("kobe") }}>-1</button>
</div>
)
}
btnClick() {
console.log(this.state.message);
}
increment = () => {
console.log(this.state.counter);
}
decrement(name) {
console.log(this.state.counter, name);
}
jsx事件传参
在执行事件函数时,有可能我们需要获取一些参数信息:比如event对象、其他参数
情况一:获取event对象
情况二:获取更多参数
{/* 情况一 */}
render() {
return (
<div>
<button onClick={this.btnClick}>按钮</button>
</div>
)
}
{/* 可以直接在定义的函数中取到event事件对象 */}
btnClick(event) {
console.log("按钮发生了点击", event);
}
{/* 情况二 */}
render() {
return (
<div>
<ul>
{
this.state.movies.map((item, index, arr) => {
return (
{/* 取到event事件对象 传到绑定的函数里面 */}
<li className="item"
onClick={ e => { this.liClick(item, index, e) }}
title="li">
{item}
</li>
)
})
}
</ul>
</div>
)
}
liClick(item, index, event) {
console.log("li发生了点击", item, index, event);
}
}
jsx条件渲染
某些情况下,界面的内容会根据不同的情况显示不同的内容,或者决定是否渲染某部分内容:
在vue中,我们会通过指令来控制:比如v-if、v-show;在React中,所有的条件判断都和普通的JavaScript代码一致;
有三个方案:条件判断语句 三元运算符 逻辑与
render() {
const { isLogin } = this.state;
// 1.方案一:通过if判断: 逻辑代码非常多的情况
let welcome = null;
let btnText = null;
if (isLogin) {
welcome = <h2>欢迎回来~</h2>
btnText = "退出";
} else {
welcome = <h2>请先登录~</h2>
btnText = "登录";
}
return (
<div>
<div>我是div元素</div>
{welcome}
{/* 2.方案二: 三元运算符 */}
<button onClick={e => this.loginClick()}>{isLogin ? "退出" : "登录"}</button>
<hr />
<h2>{isLogin ? "你好啊, coderwhy": null}</h2>
{/* 3.方案三: 逻辑与&& */}
{/* 逻辑与: 一个条件不成立, 后面的条件都不会进行判断了 */}
<h2>{ isLogin && "你好啊, coderwhy" }</h2>
{ isLogin && <h2>你好啊, coderwhy</h2> }
</div>
)
}