1.React中的组件
与Vue不同的是,在React中:组件就是一个函数或者是一个class类 !
2.认识一下函数组件
函数不能作为组件,写法需要使用jsx语法,而不是直接写函数。
jsx语法中:如果遇到 < +小写字母开头,会以标签的语法区解析。转化成同名的html标签。若遇到乐<大写字母开头,react就去渲染对应的组件,若没有定义组件,就会报错
大写字母开头表示为组件
<script src="../js/react.development.js" ></script>
<script src="../js/react-dom.development.js" ></script>
<script src="../js//babel.min.js"></script>
<script type="text/babel">
// 创建函数组件
function Demo(){
return <h1><span style={{color:"red",backgroundColor:"green"}}>111</span></h1>
}
// 由react渲染页面
ReactDOM.render(<Demo></Demo>,document.getElementById("root"))
/*
1. react解析组件标签,找到Demo组件
2. 发现是函数定义的,随后调用该函数,将返回的虚拟DOM转换成真实DOM,渲染页面
*/
</script>
3.类组件
补充一下前置知识:
严格模式中 函数执行没有被谁调用 默认是undefined。如果不是严格模式,则是指向window
class B {
add() {
console.log(this);
}
}
let b = new B().add
b()
这样的指向就为undefined
创建类组件
类组件必须继承React.Component,因为要父类的这些东西,才能够被底层进行渲染!
类组件必须自定义render函数,render必须要有返回值,返回的是jsx的html语法。
render是挂载到类组件实例上的
渲染的过程如下:
当React发现组件,判断组件类型为类组件的时候,底层就会new 该类的实例,并调用该类render方法。获取到返回的jsx的html。最后将这个虚拟DOM转换成真实DOM进行渲染!
<div class="box1"></div>
<script src="../../js/react.development.js"></script>
<script src="../../js//react-dom.development.js"></script>
<script src="../../js/babel.min.js"></script>
<script type="text/babel">
class Demo extends React.Component {
render() {
return <h1 className="title">东星军团</h1>
}
}
ReactDOM.render(<Demo></Demo>, document.querySelector('.box1'))
</script>
4.三大重要属性之一 State属性
state的作用:状态||数据 类似于Vue中的data
由于类的特性,state在类中有两种写法。
完整写法:
<div class="box1">
</div>
<script src="../../js//babel.min.js"></script>
<script src="../../js//react.development.js"></script>
<script src="../../js/react-dom.development.js"></script>
<script type="text/babel">
class Demo extends React.Component {
constructor() {
super()
this.state = {
a: '12323'
}
}
render() {
return <h1>{this.state.a}</h1>
}
}
ReactDOM.render(<Demo></Demo>, document.querySelector('.box1'))
</script>
简略写法:
<div class="box1">
</div>
<script src="../../js//babel.min.js"></script>
<script src="../../js//react.development.js"></script>
<script src="../../js/react-dom.development.js"></script>
<script type="text/babel">
class Demo extends React.Component {
state = {
a: '12323'
}
render() {
return <h1>{this.state.a}</h1>
}
}
ReactDOM.render(<Demo></Demo>, document.querySelector('.box1'))
</script>
一般获取值都采用解构赋值!!!
例如
<div class="box1">
</div>
<script src="../../js//babel.min.js"></script>
<script src="../../js//react.development.js"></script>
<script src="../../js/react-dom.development.js"></script>
<script type="text/babel">
class Demo extends React.Component {
state = {
a: '12323'
}
render() {
此处采用结构赋值
let { a } = this.state
return <h1>{a}</h1>
}
}
ReactDOM.render(<Demo></Demo>, document.querySelector('.box1'))
</script>
5.修改state属性
通过setState({})function进行重新赋值操作!
6.绑定事件
1.react的绑定事件不是原生绑定,通过自定义(合成的方式) 绑定事件
2.写法:小驼峰写法。将原生的绑定改成小驼峰写法
7.this在这里的指向问题
看一段代码
<div class="box1"></div>
<script src="../../js//react.development.js"></script>
<script src="../../js//react-dom.development.js"></script>
<script src="../..//js/babel.min.js"></script>
<script type="text/babel">
class A extends React.Component {
state = {
el: '东星军团'
}
add() {
console.log(this);
}
render() {
let { el } = this.state
return (<div><h1>{el}</h1> <button onClick={this.add}>点我修改</button></div>)
}
}
ReactDOM.render(<A></A>, document.querySelector('.box1'))
</script>
add()函数打印的this是undefined,也就是这里的this指向的是window对象。
因为react中的绑定事件不是原生事件,绑定事件实际上是一个赋值操作,然后将这个事件函数作为回调函数传到函数中去实行。事件函数不会作为绑定到节点的函数!!!
如果我们想修改state中的数据,我们必须要让this指向这个实例对象。对此,我们有两种解决办法:
方法一:回调函数
回调函数this指向的是它当前作用域指向的this
add = () => {
console.log(this);
}
方法二:使用bind函数,使其指向强制发生变化。这里讨论一下bind,apply,call
bind 和 apply,call的最大区别是 bind不是立即调用。他返回一个新的函数,这个新的函数this指向的是传递进去的第一个参数!
class A extends React.Component {
state = {
el: '东星军团'
}
add() {
console.log(this);
}
render() {
let { el } = this.state
return (<div><h1>{el}</h1> <button onClick={this.add.bind(this)}>点我修改</button></div>)
}
}
ReactDOM.render(<A></A>, document.querySelector('.box1'))