ReactP3_JSX使用_React事件绑定_this绑定问题_事件参数传递_React条件渲染_React列表渲染
这边是react学习笔记,期间加入了大量自己的理解,用于加强印象,若有错误之处还请多多指出
改变一下文章结构,方便后面来查询
JSX使用——绑定属性
普通属性的绑定
function getSizeImage(imgUrl, size) {
return imgUrl + `?param=${size}y${size}`
}
class App extends React.Component {
constructor(props) {
super(props);
this.state = {
title: "标题",
imgUrl: "http://p2.music.126.net/BeIc-sv62xZPpVBS4DjE-g==/109951164607988464.jpg",
link: "http://www.baidu.com",
}
}
render() {
const { title, imgUrl, link } = this.state;
//此处使用ES6解构语法,便于后面直接使用title等关键字而不会重复使用this使得代码变得冗余复杂
return (
<div>
{/* 绑定普通属性 */}
<h2 title={title}>我是标题</h2>
<img src={getSizeImage(imgUrl, 200)} alt=""/>
{/*必须要添加最后的斜杠*/}
<a href={link} target="_blank">百度一下</a>
</div>
)
}
}
-
在对html标签进行title绑定的时候,可以在标签中对属性参数使用{ },使用类似占位填充的方式,调用state里面的数据来进行title属性的绑定,此处在state中定义了参数title,内容为“标题”,随后在h2标签中利用{title}的方式进行调用。效果如下:
-
这边输入img的代码之前,首先在App类之外写了一个函数:
-
function getSizeImage(imgUrl, size) { return imgUrl + `?param=${size}y${size}` }
这个函数的主要作用是根据调用网站的url规范给图片传入一个用于规定图片长宽的参数,相关的参数将会被直接拼接在url之后,随后被return作为返回值
在添加图片img标签的时候切记在末尾需要加上单标签符号/
效果如下:
- a标签添加超链接的url时,使用的方法和title一样,在state声明一个属性名称和对应的值,随后在href属性后使用{属性名}的方式调用值来完成href的绑定
class的绑定
constructor(props) {
super(props);
this.state = {
active: true
}
}
render() {
const { active } = this.state;
return (
<div>
{/* 绑定class */}
<div className="box title">我是div元素</div>
<div className={"box title " + (active ? "active": "")}>我也是div元素</div>
<label htmlFor=""></label>
</div>
)
}
-
绑定class的话会显得比较奇怪,这儿用到的是className关键字,主要原因是,class在html语言中已经是作为类的关键字,为了React内部的class和html的class作出区分,在进行react框架绑定class的时候,使用关键字className;同理htmlFor为了和for关键字区分而特别设定。
-
绑定class之前,也可以先进行逻辑判断,这里先在state中设定了一个boolean值用于判断,然后在className中使用{ }内添加JSX的方式,加入三元运算符来判定是否在当前div中的class加入active关键字。
内联样式绑定
render() {
return (
<div>
{/* 绑定style */}
<div style={{color: "red", fontSize: "50px"}}>绑定style属性</div>
</div>
)
}
- 此处对div绑定内联样式的时候,如果不添加双引号直接使用red,会被认为是是一个名叫red的变量从而去寻找一个叫做red变量元素的值,所以如果要设定为red值,需要在外面加上一对双引号
- 如果属性是多个单词,中间用短杠的css样式属性,例如font-size,在绑定诸如此类的样式时,需要使用驼峰命名法,比如font-size改成fontSize…等等
React事件绑定和this绑定的问题
首先要注意两点
- React 事件的命名采用小驼峰式,而不是纯小写;
- 我们需要通过{}传入一个事件处理函数,这个函数会在事件发生时被执行
直接上代码:
提供以下一种构造器生成的结构,里面包含message,counter以及一个给函数绑定当前指针操作的语句
constructor(props) {
super(props);
this.state = {
message: "你好啊",
counter: 100
}
this.btnClick = this.btnClick.bind(this);
}
先讲重点,之前提到过,为什么要有一步绑定指针的操作,组件在被执行的时候,是被调用到react的内部框架去调用的,而函数执行时候,并不是运行在组件内,而是运行在框架内的,如果没有this绑定的操作,函数的this就不会指向当前组件。这样在调用this的时候,调用的是一个undefined,同样的,就没法通过this去找到对应的state和里面的值了
绑定事件的三种方式
this.btnClick = this.btnClick.bind(this);//为了方便阅读重新贴一遍,不代表要写两次
render() {
return (
<div>
{/* 方案一: bind绑定this(显示绑定) */}
<button onClick={this.btnClick}>按钮1</button>
<button onClick={this.btnClick}>按钮2</button>
<button onClick={this.btnClick}>按钮3</button>
</div>
)
}
btnClick() {
console.log(this);
console.log(this.state.message);
}
- 第一种方案是显示绑定,直接用bind方法,赋予一个指向当前组件的this指针,而后调用btnClick方法,对组件中的内容进行操作
render() {
return (
<div>
{/* 方案二: 定义函数时, 使用箭头函数 */}
<button onClick={this.increment}>+1</button>
</div>
)
}
increment = () => {
console.log(this.state.counter);
}
-
第二种方法是利用箭头函数赋值去定义函数
箭头函数介绍:
这里需要对箭头函数进行一定的介绍,箭头函数( )=>{ },ES6中的新特性,关键箭头函数中永远不绑定this,只会从使用箭头函数的上一层去寻找this指针,这种箭头函数赋值的方式在ES6中称为:class fields,即类的成员变量。使用箭头函数赋值定义函数的缺点是定义函数的时候一般使用声明函数的方法,阅读起来会变扭
render() {
return (
<div>
{/* 方案三(推荐): 直接传入一个箭头函数, 在箭头函数中调用需要执行的函数*/}
<button onClick={() => { this.decrement("xxx") }}>-1</button>
</div>
)
}
decrement(param) {
console.log(this.state.counter, param);
}
- 第三种方法是直接执行箭头函数,在箭头函数中调用需要执行的函数
最大的优点是,由于箭头函数的特性,运行在render函数中的箭头函数会获的来自于render函数的指针,而箭头函数又会隐式的,将this指针传给待执行的函数,解决了this绑定的问题
事件参数传递
在执行事件函数时,有可能我们需要获取一些参数信息:比如event对象、其他参数
- 情况一:获取event对象
如果需要使用操作event对象,假如用不到this,那么直接传入函数就可以获取到event对象
render() {
return (
<div>
<button onClick={this.btnClick.bind(this)}>按钮</button>
</div>
)
}
btnClick(event) {
console.log("按钮发生了点击", event);
}
情况二:获取更多参数
若是多个参数情况下,最好是传入一个箭头函数,主动执行事件函数,并且传入相关的其他参数
可以理解为,利用箭头函数作为中转站,把箭头函数的event事件对象作为参数传递到执行函数中
render() {
return (
<div>
<ul>
{
this.state.movies.map((item, index, arr) => {
return (
<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);
}
React条件渲染
条件渲染分成三种方法:
1、条件判断语句
2、三元运算符
3、&&运算符
先提供数据
constructor(props) {
super(props);
this.state = {
isLogin: true
}
}
- 条件判断语句适用于逻辑较多的情况下
const { isLogin } = this.state;
// 方案一:通过if判断: 逻辑代码非常多的情况
let welcome = null;
let btnText = null;
if (isLogin) {
welcome = <h2>欢迎</h2>
btnText = "退出";
} else {
welcome = <h2>起开</h2>
btnText = "坐下";
}
- 三元运算符适合逻辑比较简单的情况下
{/* 方案二: 三元运算符 */}
<button onClick={e => this.loginClick()}>{isLogin ? "退出" : "登录"}</button>
<h2>{isLogin ? "你好啊, DD": null}</h2>
loginClick() {
this.setState({
isLogin: !this.state.isLogin
})
}
-
逻辑与运算,主要利用了js中的逻辑短路特性
逻辑短路简单的理解为: A&&B,如果A为真,那么直接以B的值为准,第一个条件不成立,后面的都不会判断了 A||B,如果A为真,那么直接以A的值为准,第一个条件成立,后面的都不会判断了
{/* 方案三: 逻辑与&& */}
<h2>{ isLogin && "你好啊, DD" }</h2>
{ isLogin && <h2>你好啊, DD</h2> }
列表渲染
列表渲染主要用到了几种高阶函数map(),filter(),slice()
直接贴代码,不赘述
constructor(props) {
super(props);
this.state = {
names: ["abc", "cba", "nba", "mba", "dna"],
numbers: [110, 123, 50, 32, 55, 10, 8, 333]
}
}
render() {
return (
<div>
<h2>名字列表</h2>
<ul>
{
this.state.names.map(item => {
return <li>{item}</li>
})
}
</ul>
<h2>数字列表(过滤1)</h2>
<ul>
{
this.state.numbers.filter(item => {
return item >= 50;
}).map(item => {
return <li>{item}</li>
})
}
</ul>
<h2>数字列表(过滤2)</h2>
<ul>
{
this.state.numbers.filter(item => item >= 50).map(item => <li>{item}</li>)
}
</ul>
<h2>数字列表(截取)</h2>
<ul>
{
this.state.numbers.slice(0, 4).map(item => {
return <li>{item}</li>
})
}
</ul>
</div>
)
}
控制台期间会产生一个警告,主要就是需要给每一项增加一个唯一标识key,当下暂且不需要管,未来会提到
当下事情有点多,后面如果有时间会补充高阶函数的具体使用方法
感谢coderwhy(王红元老师)的课程
爱生活,爱猪猪