函数组件
代码示例:
// 1.创建函数式组件
function MyComponent(){
console.log(this);//此时的this是undefined,因为babel编译后开启了严格模式
return <h2>我是用函数定义的组件,适用于【简单组件】的定义</h2>
}
//2.渲染组件到页面
ReactDOM.render(<MyComponent/>,document.getElementById('test'))
执行了ReactDOM.render(…之后,发生了什么?
- React解析组件标签,找到了MyComponent组件。
- 发现组件是使用函数定义的,随后调用该函数,将返回的虚拟DOM转为真是DOM,随后呈现在页面中。
类组件
类相关的几个概念:1)构造器 2)继承 3)super
关于类的总结
- 类中的构造器不是必须写的,要对实例进行一些初始化的操作,如添加指定属性时才写。
- 如果A类继承了B类,且A类中写了构造器,那么A类构造器中的super是必须要调用的。
- 类中所定义的方法,都是放在了类的原型对象上,供实例去使用。
代码示例:
// 1.创建类式组件
class MyComponent extends React.Component(){
render(){
//render是放在MyComponent原型对象上的,供实例使用
//render的this是MyComponent的实例对象(MyComponent组件实例对象)
return <h2>我是用类定义的组件,适用于【复杂组件】的定义</h2>
}
}
//2.渲染组件到页面
ReactDOM.render(<MyComponent/>,document.getElementById('test'))
执行了ReactDOM.render(…之后,发生了什么?
- React解析组件标签,找到了MyComponent组件。
- 发现组件是使用类定义的,随后new出来该类的实例,并通过该实例调用到原型上的render方法。
- 将render返回的虚拟DOM转为真实DOM,随后呈现在页面中。
构造器
不是必须的,可以省略。构造器中的操作
- 调用React.Component的super、
- 初始化状态(state)、
- 解决类中函数this指向的问题
注意:类组件里面,构造器只调用了一次,render调用了1+n次,n是状态更新的次数
构造器是否接受props,是否传递给super,取决于是否希望构造器中通过this访问props
组件(实例)的三大核心属性
函数组件是没有实例的,所以没有这三大核心,但是最新版React为函数组件增加了hooks属性,使函数组件也可以实例化。
1.state(状态)
state是组件对象最重要的属性,值是对象(可以包含多个key-value的组合),组件被成为“状态机”,通过更新组件的state来更新对应的页面显示(重新渲染组件)。
注意事项:
- 组件中render方法中的this为组件实例对象
- 组件自定义的方法中this为undefined,如何解决?
1)强制绑定this:通过函数对象的bind()
2)箭头函数: a= ()=>{} - 状态数据,不可自己更改,必须调用setState进行更新,且更新是一种合并,不是替换
- state可以不必在构造器中定义,直接类里赋值也可以
2.props
通过标签属性从组件外向组件内传递的数据。每个组件对象都会有props(properties的简写)属性,组件标签的所有属性都保存在props中。props是只读的。
可以使用插件PropTypes限制传入值的类型和必要性。 这个插件是外部插件,需要自己引入。React15.5 版本以前PropTypes是挂载在React上的,以后的担保就独立成插件了,需要自己安装。
可以使用defaultProps为传入的值设置默认值。
函数组件和类组件都可以使用props,函数组件以参数的形式使用。
3.refs
不能使用字符串作为ref,不要过度使用ref,建议使用如下方法创建ref:
- 回调函数ref。将内联函数或实例自身的函数绑定在ref上都可以,不重要:但是这两种方法是有区别的,内联函数当状态有变化时,需要重新执行,但是实例上绑定的函数不会有这个问题,不过区别不大,都可以使用。
- 使用createRef API创建【官方推荐使用】。React.createRef调用后可以返回一个容器,该容器可以存储被ref所标识的节点。