众所周知,react提供了两种形式的UI组件:函数式or类式
- 
函数式 function Welcome(props) { return <h1>Hello, {props.name}</h1>; } 复制代码
- 
类式 class Welcome extends React.Component { render() { return <h1>Hello, {this.props.name}</h1>; } } 复制代码
将函数式组件转化为类组件
class ComponentName extends React.Component{}- 添加
render()- 将函数体移入
render()- 在
render()中使用this.props替换props- 清楚原有函数式组件
特性
| 特性 | 类组件(class) | 函数组件(function) | 
|---|---|---|
| state | √ | √ (通过State Hook) | 
| 生命周期 | √ | √ (通过Effect Hook) | 
HOOK
HOOK是什么?
	 Hook 是一个特殊的函数,它可以让你钩入React 的特性。例如,useState 是允许你在 React 函数组件中添加 state 的 Hook。
State Hook
 state相关
例子
import React, { useState } from 'react';
function Example() {
  // 声明一个叫 "count" 的 state 变量
  const [count, setCount] = useState(0);
  return (
    <div>
      <p>You clicked {count} times</p>
      <button onClick={() => setCount(count + 1)}>
        Click me
      </button>
    </div>
  );
}
复制代码 等价的类组件
class Example extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      count: 0
    };
  }
  render() {
    return (
      <div>
        <p>You clicked {this.state.count} times</p>
        <button onClick={() => this.setState({ count: this.state.count + 1 })}>
          Click me
        </button>
      </div>
    );
  }
}
复制代码API
| API | 作用 | 写法 | 说明 | 
|---|---|---|---|
| useState | 在函数调用时保存变量的方式,与 class 里面的 this.state提供的功能完全相同 | const [eg, setEg] = useState(0); | eg:state;setEg:修改对应state;useState(0):设置初始值为0 | 
Effect Hook
	可以把 useEffect Hook 看做 componentDidMount,componentDidUpdate 和 componentWillUnmount 这三个函数的组合。
无需清除的 effect
 **在 React 更新 DOM 之后运行一些额外的代码。**比如发送网络请求,手动变更 DOM,记录日志,这些都是常见的无需清除的操作。
import React, { useState, useEffect } from 'react';
function Example() {
  const [count, setCount] = useState(0);
  // 类似 componentDidMount | componentDidUpdate 
  useEffect(() => {
    // 更新DOM
    document.title = `You clicked ${count} times`;
  });
  return (
    <div>
      <p>You clicked {count} times</p>
      <button onClick={() => setCount(count + 1)}>
        Click me
      </button>
    </div>
  );
}
复制代码	通过使用这个 Hook,React 会保存你传递的函数(我们将它称之为 “effect”),并且在执行 DOM 更新之后调用它。 将 useEffect 放在组件内部可以在 effect 中直接访问 state 变量。
需要清除的 effect
 例如订阅外部数据源。
 class
class FriendStatus extends React.Component {
  constructor(props) {
    super(props);
    this.state = { isOnline: null };
    this.handleStatusChange = this.handleStatusChange.bind(this);
  }
  componentDidMount() {
    ChatAPI.subscribeToFriendStatus(
      this.props.friend.id,
      this.handleStatusChange
    );
  }
  componentWillUnmount() {
    ChatAPI.unsubscribeFromFriendStatus(
      this.props.friend.id,
      this.handleStatusChange
    );
  }
  handleStatusChange(status) {
    this.setState({
      isOnline: status.isOnline
    });
  }
  render() {
    if (this.state.isOnline === null) {
      return 'Loading...';
    }
    return this.state.isOnline ? 'Online' : 'Offline';
  }
}
复制代码 hook
import React, { useState, useEffect } from 'react';
function FriendStatus(props) {
  const [isOnline, setIsOnline] = useState(null);
  useEffect(() => {
    function handleStatusChange(status) {
      setIsOnline(status.isOnline);
    }
    ChatAPI.subscribeToFriendStatus(props.friend.id, handleStatusChange);
    // Specify how to clean up after this effect:
    return function cleanup() {
      ChatAPI.unsubscribeFromFriendStatus(props.friend.id, handleStatusChange);
    };
  });
  if (isOnline === null) {
    return 'Loading...';
  }
  return isOnline ? 'Online' : 'Offline';
}
复制代码 React 将按照 effect 声明的顺序依次调用组件中的每一个 effect。
 为什么要在 effect 中返回一个函数? 这是 effect 可选的清除机制。每个 effect 都可以返回一个清除函数。
通过跳过 Effect 进行性能优化(useEffect的第二个参数)
useEffect(() => {
  document.title = `You clicked ${count} times`;
}, [count]); // 仅在 count 更改时更新
复制代码优缺点
- 
一般来说,类组件的性能消耗较函数式组件大,包括生成实例时使用的内存及shouldComponentUpdate不正确引起的不必要的更新。 如果类组件没有指明shouldComponentUpdate生命周期函数,组件的父组件更新时不管组件的props是否改变了组件一定更新 如果组件是PureComponent的实例的话,对组件实例的先前props/state和后来props/state作浅比较(很高效),再决定是否更新组件 tips:props中的obj对象内容发生变化是无法被react通过浅层对比(default)察觉的! 
- 
类组件不能很好的压缩 
- 
实际开发中,类组件的生命周期常常包含一些不相关的逻辑 
memo
	React.memo为高阶组件,React.memo 仅检查 props 变更,并通过记忆组件渲染结果的方式来提高组件的性能。类似PureComponent。
	不同的是memo是生成函数组件浅比较的是Props,PureComponent用来生成class组件,比较Props和state
 默认情况下其只会对复杂对象做浅层对比,如果你想要控制对比过程,那么请将自定义的比较函数通过第二个参数传入来实现。
function MyComponent(props) {
  /* 使用 props 渲染 */
}
function areEqual(prevProps, nextProps) {
  /*
  如果把 nextProps 传入 render 方法的返回结果与
  将 prevProps 传入 render 方法的返回结果一致则返回 true,
  否则返回 false
  */
}
export default React.memo(MyComponent, areEqual);
复制代码总结
 基于优缺点中的内容,由于Hooks的使用,不具备state和生命周期已经不再是函数式组件的缺陷,所以他们由于内存使用以及更新渲染上的优势,更应该被使用。所以,一般情况下函数式组件是较好的选择,非要使用类组件的时候,也应该使用PureComponent。























![[桜井宁宁]COS和泉纱雾超可爱写真福利集-一一网](https://www.proyy.com/skycj/data/images/2020-12-13/4d3cf227a85d7e79f5d6b4efb6bde3e8.jpg)

![[桜井宁宁] 爆乳奶牛少女cos写真-一一网](https://www.proyy.com/skycj/data/images/2020-12-13/d40483e126fcf567894e89c65eaca655.jpg)
