jsx语法
一、jsx语法中有两种标签:
1、普通的html标签:在组件中返回出去渲染的标签内容不需要像原生js那样加引号
2、组件标签:例如入口文件index.js中,渲染App组件内容时,写成<App />首字母必须大写
二、使用变量、js表达式、注释,外层要加{}
三、给元素加类名需要通过className属性,class会冲突
四、使用label标签与input关联时,label里的for需要写成htmlFor(表明这是html的for,不是js的for循环)
五、想让react不对标签转义,也就是<h1>text</h1> ==》 大大的text 的方法:
在标签中新增dangerouslySetInnerHTML属性,绑定js表达式需要{}包裹,所以先加一个{},然后里面是一个对象,键是__html,值是渲染的数据
数据驱动的设计思想和事件绑定(重点)
设计思想
React基于数据驱动,所有操作都不直接操作dom,而是操作数据。
组件被创建的最初始的时间,constructor会最先被执行,在constructor中定义需要的数据。
super是关键字,它指代父类的实例(即父类的this对象),子类必须在constructor方法中调用super方法,否则新建实例时会报错,因为子类没有自己的this对象,而是继承父类的this对象,然后对其进行加工,如果不调用super方法,子类就得不到this对象。
constructor(props){
super(props); 【(constructor和super)是固定写法】
this.state = { 【定义组件的数据,必须写在this.state里面】
inputValue: "Hello world",
};
}
在JSX语法里,如果标签属性等于一个js变量或js表达式的时候,外面要包裹一个花括号
<input type="text" value={this.state.inputValue}/>
事件绑定
1、绑定事件
React事件名的写法必须是驼峰式,如onChange,写成onchange的话会报错,然后在组件中定义事件(class类)
onChange={this.handleInputChange.bind(this)}
2、事件的this默认指向undefined
react触发事件时,内部的this并不指向当前组件,默认是undefined,所以需要使用 bind()方法改变函数内部的this的指向。
bind()方法是将调用bind方法的对象的this指向改为bind的参数,这里bind参数为this,这个this是render的this,指向当前组件,所以调用bind以后该方法的this就指向当前组件。
另一种解决办法是将handleInputChange函数改为箭头函数,因为箭头函数的this指向为最外层对象,这里即是当前组件。
3、修改state中的数据
需要通过this.setState ( { } )方法来修改
练习:
一、实现TodoList新增li功能
1、将input框里的内容渲染到数组中
给input框绑定onKeyUp事件,通过e.keyCode是否等于13,判断按下的键是否为回车键,把input框的内容加到数组中。
handleKeyUp(e) {
if (e.keyCode === 13) {
const list = [...this.state.list, this.state.inputValue]; 拷贝一个list副本,然后加上当前的inp框输入的内容,然后赋值给state中的list
this.setState({ list });【ES6语法,键和值一样的时候写一个就可以了】
}
}
2、将数组中的数据遍历渲染到标签里
this.state.list.map((value,index)=>{
return <li key={index}>{value}</li>
})
在JSX语法中,要写js表达式,一定要包在花括号里。
map是数组遍历的方法,里面接收参数并执行语句,返回的内容要使用return。return的结果中要使用变量时一样要加花括号。
二、实现TodoList删除功能
点击li,相应li的内容被删除
(1)给li绑定onCLick事件
<li key={index} onClick={this.handleItemClick.bind(this, index)}>
要点击li相应的li被删除,需要给函数传入参数index,参数写在后面的bind方法里。
(2)删除内容的函数
handleItemClick(index) {
const list = [...this.state.list];【调用数据时,最好使用解构赋值拷贝一个副本出来,避免使用过程中出现问题】
list.splice(index, 1);
this.setState({ list });
}
细节优化
1、bind(this)是在用户触发事件的时候,都会重新生成一个新的函数,这样性能比较低。
解决方法:
可以把this的绑定放在constructor里面,state前,开始就把这个事件的this改过来
但是传入参数的函数就不能这样在constructor里绑定了,因为这种函数确实需要每次调用的时候都生成一次,如onClick={this.handleItemClick.bind( this, index ) }
2、可以把对标签的循环渲染代码放在一个方法里,将循环的结果使用return返回,在下面直接调用这个方法,这样JSX看起来就非常简洁了。
比如:getItemList() {
return this.state.list.map((value, index) => {
return (
<li key={index} onClick={this.handleItemClick.bind(this, index)}>
{value}
</li>
);
});
}
<ul>{this.getItemList()}</ul>
————————————————————
3、在React中给一个标签添加样式class的时候,不能使用class属性,它会认为和定义类的class混淆,应该使用className属性来添加类名