React 的几种组件
函数组件与类组间
类组件
我们常写的组件都是下面的形式:
class Name extends Component {
constructor(props) {
super(props);
this.state = { }
}
render() {
return ( );
}
}
export default Name;
这种组件就是类组件,它是用 ES6 的语法类来写的,constructor
函数组件
而函数组件的书写方式如下:
function Name(props){
return( )
}
函数组件就是一个函数,它接收一个 props,返回 jsx。
受控组件与非受控组件
受控组件
受控组件的值由 props 或 state 传入,用户在元素上交互或输入内容会引起应用 state 的改变。
在 state 改变之后重新渲染组件,我们才能在页面中看到元素中值的变化,假如组件没有绑定事件处理函数改变 state,用户的输入是不会起到任何效果的,这也就是“受控”的含义所在。
组件的值----state控制; 组件值得变换---通过触发onChange事件,然后由this.setState负责改变;
在 react 中,form 的 input,select 等通常都是受控组件。
在一个受控组件中,表单数据是由 React 组件来管理的。
demo:
class ControlledInput extends React.Component {
constructor() {
super()
this.state = {value: 'Please type here...'}
}
handleChange(event) {
console.log('Controlled change:',event.target.value)
this.setState({value: event.target.value})
}
render() {
return (
<label>
Controlled Component:
<input type="text"
value={this.state.value}
onChange={(e) => this.handleChange(e)}
/>
</label>
);
}
}
非受控组件
非受控组件即是组件的状态变化不受 state 的控制。想要获取非受控组件,我们需要使用一个特殊的ref属性,同样也可以使用defaultValue属性来为其指定一次性的默认值。
文件 input 标签是非受控组件:
在一个非受控组件,这时表单数据将交由 DOM 节点来处理。
demo:
class UncontrolledInput extends React.Component {
constructor() {
super();
}
handleChange() {
console.log('Uncontrolled change:',this.input.value);
}
render() {
return (
<label>
Uncontrolled Component:
<input type="text"
defaultValue='Please type here...'
ref={(input) => this.input = input}
onChange={() =>this.handleChange()}
/>
</label>
);
}
}
有状态组件和无状态组件
有状态组件
日常用的组件,它有生命周期,有 state,主要用来定义交互逻辑和业务数据。这样的组件当中看到对 this.state 的初始化,或 this.setState 方法的调用等等。
有状态组件可以叫做容器组件。
特点:
- 包含生命周期和其他附加方法;
- 自身拥有 state;
- 多为类定义组件
作用:
- 主要关注交互逻辑与业务数据;
demo:
class Name extends Component {
constructor(props) {
super(props);
this.state = {
name:'有状态组件'
}
}
componentDidMount() {
}
static getDerivedStateFromProps(nextProps, prevState) {
}
shouldComponentUpdate(nextProps, nextState, nextContext) {
}
render() {
return (
<div>
<p>
{this.state.name}
</p>
</div>
);
}
getSnapshotBeforeUpdate(prevProps, prevState) {
}
componentDidUpdate(prevProps, prevState){
}
componentWillUnmount() {
}
}
export default Name;
无状态组件
无状态组件就是不含有状态和对状态的处理的组件,它没有生命周期,没有 state,一般这样的组件中只能看到对 this.props 的调用,可以看成是将 render 单独抽出的一个函数组件。它只展示 UI 而不关注逻辑。无状态组件比有状态组件性能更高。
无状态组件可以叫做展示组件。
特点:
- 不包含任何状态,但可以包含属性;
- 无状态组件生成时不用实例化;
- 无状态组件没有this,ref和生命周期;
作用:
- 单纯的UI表现,不用涉及太多的交互;
- 不用对DOM做过多的操作;
demo:
function Name(props){
return(
<div>
<p>无状态组件</p>
</div>
)
}
高阶组件与高阶函数
简单的理解,返回组件的组件就是高阶组件,返回函数的函数就是高阶函数。
高阶组件
定义:接受一个组件作为参数,并返回一个新的组件。它是一个组件而不是一个函数。
形式:
包装方式:属性代理与反向代理
特点:不会改变被包装组件的内容,结构,不会复制它的行为,是利用它创建一个新的行为。
- 属性代理
定义:高阶组件接受外界实行,然后通过包装环境传递给被包装组件。
demo:
function HOC(Com) {
其他处理;
return class [Name] extends Component {
constructor(props) {
super(props);
}
render() {
return (
<div>
<Com {...this.props} />
</div>
)
}
}
}
- 反向代理
定义:指定的组件作为另一个组件的父类,而继承了的组件就是一个高阶组件 特点: 1)该组件是被动被继承; 2)高阶组件可以通过 this 来获取父类的 state,props,生命周期函数和渲染函数; 3)一般来说,若调用父类的生命周期和渲染函数,用super来调用,以便保护父类的生命周期和渲染函数; 优势: 渲染劫持:高阶组件通过props属性来决定父类的渲染树是否被渲染(props不能创建或者改变props的名称,但可以更改和操作props的值)
demo:
function HOC(B){
return class [A] extends B{
render(){
return super.render();
}
}
高阶函数
高阶函数的基本概念:
- 函数可以作为参数传递
- 函数可以作为返回值输出
参考
[高阶函数与高阶组件](