• React中的函数组件详解


    1. 创建方式

     //  写法一
    const Hello = (props) => {      
        return 
    {props.message}
    } // 写法二 const Hello = props =>
    {props.message}
    // 写法三 function Hello(props) { return
    {props.message}
    }
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12

    2. 函数组件代替类组件

    面临的问题

    • 函数组件没有state => React v16.8.0推出Hooks API,其中的一个API叫做useState可以解决问题
    • 函数组件没有生命周期 => React v16.8.0推出Hooks API,其中的一个API叫做useEffect可以解决问题

    我们对比一下两种组件实现 n + 1 的例子

    类组件

    class App extends React.Component {
        constructor(props) {
            super(props);
            this.state = {
                n: 0
            }
        }
    
        addNum = () => {
            this.setState({n: this.state.n + 1})
        }
    
        render() {
            return (
                
    n:{this.state.n}
    ) } }
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21

    函数组件

    const App = props => {
        const [n,setN] = React.useState(0)
        function addNum(){
            setN(n + 1)
        }
        return (
            
    {n}
    ) }
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12

    相比之下函数组件更为简洁一些

    使用 useEffect 解决生命周期问题

    1. 模拟 componentDidMount 首次渲染

      useEffect(() => { // 模拟componentDidMount 首次渲染
      console.log(‘use effect’)
      },[]) // 空数组必须写

    2. 模拟 componentDidUpdate

      const [n, setN] = React.useState(0)
      useEffect(() => { // 模拟 componentDidUpdate
      console.log(‘n 变化了’)
      },[n]) // 数组里面可以写多个参数表示监听多个变量

      useEffect(() => { // 模拟 componentDidUpdate
      console.log(‘任意属性变更了’)
      }) // 不写数组表示监听所有 useState 的变量
      // 但是这样在第一次渲染时也会触发函数的执行
      解决方法使用自定义Hook 见下一标题

    3. 模拟componentWillUnmount

      useEffect(() => {
      return () => {
      console.log(‘Child 销毁了’)
      }
      }) // 返回一个函数 在销毁时执行

    4. constructor
      函数组件执行的时候,就相当于constructor

    5. shouldComponentUpdate
      后面的 React.memo和useMemo可以解决

    6. render
      函数组件的返回值就是render的返回值.

      // 模拟render里面写逻辑
      const X = (props) => {
      console.log(‘我是要写的逻辑’)
      return (

      逻辑模拟

      )
      }

      const App = props => {
      let [childVisible, setChildVisible] = useState(true)

      const changeVisible = () => {
          setChildVisible(!childVisible)
      }
      
      return (
          
      {childVisible ? : } {/*{childVisible ? : null}*/}
      )
      • 1
      • 2
      • 3
      • 4
      • 5
      • 6
      • 7
      • 8
      • 9
      • 10
      • 11
      • 12
      • 13

      } // 一个函数便是一个组件

    3. 自定义 Hook 之 useUpdate
    解决上面 n 值初次渲染就执行的问题

    const App = props => {
        const [n, setN] = useState(0)
        const onClick = () => {
            setN(n + 1)
        }
        const [nUpdateCount, setNUpdateCount] = useState(0)
        useEffect(() => {    // 初次渲染就执行 + 1
            setNUpdateCount(nUpdateCount + 1)
        }, [n])
        useEffect(() => {    // 初次渲染就执行 判断是否大于1 
            if(nUpdateCount > 1){
                console.log('n变了')
            }
        },[nUpdateCount])
        return (
            
    n值变成了:{n}
    ) } // 通过使用两次 useEffect 第一个触发第二个 useEffect 函数计数,大于0便是n值变化了
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22

    上面的代码很乱 改进一下

    const useX = (fn, dep) => {   // 这就是自定义 Hook 这就可以抽离成别的文件
        const [count, setCount] = useState(0)
        useEffect(() => {
            setCount(x => x + 1)
        }, [dep])
        useEffect(() => {
            if (count > 1) {
                fn()
            }
        }, [count,fn])
    }
    
    const App = props => {
        const [n, setN] = useState(0)
        const onClick = () => {
            setN(n + 1)
        }
        useX(() => {
            console.log('n 变化了')
        }, n)
        return (
            
    n值变成了:{n}
    ) }
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27

    先自我介绍一下,小编13年上师交大毕业,曾经在小公司待过,去过华为OPPO等大厂,18年进入阿里,直到现在。深知大多数初中级java工程师,想要升技能,往往是需要自己摸索成长或是报班学习,但对于培训机构动则近万元的学费,着实压力不小。自己不成体系的自学效率很低又漫长,而且容易碰到天花板技术停止不前。因此我收集了一份《java开发全套学习资料》送给大家,初衷也很简单,就是希望帮助到想自学又不知道该从何学起的朋友,同时减轻大家的负担。添加下方名片,即可获取全套学习资料哦

  • 相关阅读:
    客户案例|用友NC财务系统上云
    redis非关系型数据库
    Java:PHP与Java——哪个更适合你?
    docker常用命令大全
    (AtCoder Beginner Contest 280) E - Critical Hit (经典的组合数学问题)
    SpringCloudAlibaba-微服务-Nacos服务配置
    Java 使用Lock、Condition的生产者与消费者问题(JUC)
    PHP面试题大全
    机器学习(11)---降维PCA
    软件设计原则-接口隔离原则讲解以及代码示例
  • 原文地址:https://blog.csdn.net/m0_66557301/article/details/126113979