一、react的组件
React的组件相对于Vue更加的灵活和多样,按照不同的方式可以分成很多类组件。
- 根据组件的定义方式:函数组件和类组件;
- 根据组件内部是否有状态需要维护:无状态组件和有状态组件;
- 根据组件的不同职责:展示型组件和容器型组件;
总的来说,函数组件、无状态组件、展示型组件主要关注UI的展示;类组件、有状态组件、容器型组件主要关注数据逻辑。
二、类组件
1.要求
-
组件的名称是大写字符开头(无论类组件还是函数组件)
-
类组件需要继承自 React.Component
-
类组件必须实现render函数
class组件里的定义:
-
constructor是可选的,我们通常在constructor中初始化一些数据;
-
this.state中维护的就是我们组件内部的数据;
-
render() 方法是 class 组件中唯一必须实现的方法;
render函数的返回值(当 render 被调用时,它会检查 this.props 和 this.state 的变化并返回以下类型之一 ):
-
React 元素:通常通过 JSX 创建。例如,<div/> 会被 React 渲染为 DOM 节点,<MyComponent/> 会被 React 渲染为自定义组件;无论是 <div/> 还是 <MyComponent/> 均为 React 元素。
-
数组或 fragments:使得 render 方法可以返回多个元素。
-
Portals:可以渲染子节点到不同的 DOM 子树中。
-
字符串或数值类型:它们在 DOM 中会被渲染为文本节点。
- 布尔类型或 null:什么都不渲染 。
import React from "react";
class App extends React.Component {
constructor() {
super()
this.state = {
message: 'kk'
}
}
render() {
return (
<div>
{this.state.message}
</div>
)
}
}
export default App
三、函数组件
函数组件是使用function来进行定义的函数,只是这个函数会返回和类组件中render函数返回一样的内容。
特点:
-
没有生命周期,也会被更新并挂载,但是没有生命周期函数;
-
this关键字不能指向组件实例(因为没有组件实例);
-
没有内部状态(state)。
function App() {
return (
<div>我是函数组件</div>
)
}
export default App
四、受控组件和非受控组件
1.定义
比如input绑定了value值,我们需要使用onChange绑定一个事件input才能继续输入值,这个称为表单组件,而非受控组件是没有绑定value属性的。
受控组件设置value来设置默认值,非受控组件设置defultValue来设置默认值
import React, { PureComponent } from 'react'
export class App extends PureComponent {
constructor() {
super()
this.state = {
username: "kk"
}
}
inputChange(event) {
console.log('inputChange', event.target.value)
this.setState({username: event.target.value})
}
render() {
const { username } = this.state
return (
<div>
{/* 受控组件 */}
<input type="text" value={username} onChange={e => this.inputChange(e)} />
{/* 非受控组件 */}
<input type="text" />
<h2>username: {username}</h2>
</div>
)
}
}
export default App
五、高阶组件
1.定义
首先, 高阶组件 本身不是一个组件,而是一个函数;其次,这个函数的参数是一个组件,返回值也是一个组件。
import React, { PureComponent } from 'react'
// 1.定义高阶组件
function Hoc(Cpn) {
// 定义类组件、或者定义函数组件
class NewCpn extends PureComponent {
render() {
return <Cpn/>
}
}
return NewCpn
}
class HelloWorld extends PureComponent {
render() {
return <div>Hello World</div>
}
}
const HocComponent = Hoc(HelloWorld)
export class App extends PureComponent {
render() {
return (
<div>
<HocComponent></HocComponent>
</div>
)
}
}
export default App
应用场景:
1.props的增强(共享props)
2.利用高阶组件来共享Context
3.登录鉴权
缺陷:
-
HOC需要在原组件上进行包裹或者嵌套,如果大量使用HOC,将会产生非常多的嵌套,这让调试变得非常困难;
-
HOC可以劫持props,在不遵守约定的情况下也可能造成冲突;
六、fragment
在之前的开发中,我们总是在一个组件中返回内容时包裹一个div元素,我们又希望可以不渲染这样一个div应该如何操作呢:
-
使用Fragment,允许将子列表分组,而无需向 DOM 添加额外节点
-
React还提供了Fragment的短语法,它看起来像空标签 <> </>;但是,如果我们需要在Fragment中添加key,那么就不能使用短语法。
import React, { PureComponent, Fragment } from 'react'
export class App extends PureComponent {
render() {
return (
// 1.完整写法
// <Fragment>
// <h2>哈哈哈</h2>
// <h3>哇哇哇</h3>
// </Fragment>
// 2.空标签写法
<>
<h2>哈哈哈</h2>
<h3>哇哇哇</h3>
</>
)
}
}
export default App