React 第七章 Hooks

2024-03-07 1057阅读

温馨提示:这篇文章已超过422天没有更新,请注意相关的内容是否还可用!

Hooks 基本介绍

HookReact 16.8 的新增特性。它可以让你在不编写 class 的情况下使用 state 以及其他的 React 特性。

React 第七章 Hooks
(图片来源网络,侵删)

Hooks 的出现,首先能解决如下的一些问题:

  • 告别令人疑惑的生命周期
    • 例如下面的例子,相同的代码在不同的生命周期中存在了两份
      import React from "react";
      // 类组件
      class App extends React.Component {
        constructor() {
          super();
          this.state = {
            count : 0
          }
        }
        componentDidMount(){
          document.title = `你点击了${this.state.count}次`;
        }
        componentDidUpdate(){
          document.title = `你点击了${this.state.count}次`;
        }
        render() {
          return (
            
              

      You clicked {this.state.count} times

      this.setState({ count: this.state.count + 1 })}> Click me ) } } export default App;
      • 告别类组件中烦人的 this
        • 在类组件中,会存在 this 的指向问题,例如在事件处理函数中,不能直接通过 this 获取组件实例,需要修改 this 指向
        • 告别繁重的类组件,回归前端程序员更加熟悉的函数

          另外,Hooks 的出现,还有更加重要的一个信号,那就是整个 React 思想上面的转变,从“面向对象”的思想开始转为“函数式编程”的思想。这是编程范式上面的转变。

          编程范式:

          • 命令式编程:告诉计算机怎么做(How),我们需要给计算机指明每一个步骤
            • 面向过程
            • 面向对象
            • 声明式编程:告诉计算机我要什么(What
              • 函数式编程
              • DSL(领域专用语言,HTML、CSS、SQL

                声明式编程并不是新的产物,它是和命令式编程同期出现的。但是,早期更加流行命令式编程。不过随着近几年整个项目工程越来越复杂,以前的命令式编程就有点力不从心,所以现在慢慢开始流行声明式编程。

                因此当你学习 Hooks 的时候,会发现突然多了一些以前不熟悉的概念,例如:纯函数、副作用、柯里化、高阶函数等概念。

                当然,你可能好奇“面向对象”和“函数式编程”有什么区别,这里推荐一篇文章:

                https://www.imaginarycloud.com/blog/functional-programming-vs-oop/

                Hook 就是 JavaScript 函数,但是使用它们会有两个额外的规则:

                • 只能在函数最外层调用 Hook。不要在循环、条件判断或者子函数中调用。
                • 只能在 React 的函数组件中调用 Hook。不要在其他 JavaScript 函数中调用。

                  useStateuseEffect

                  React 内置了一些实用的 Hook,并且随着 React 版本的更新,Hook 的数量还在持续增加当中。

                  入门阶段,我们掌握两个最常用的 Hook,一个是为函数组件添加状态的 useState,另一个是处理函数副作用的 useEffect

                  useState

                  • 基本使用
                    import { useState } from 'react';
                    function App(props) {
                      let [count, setCount] = useState(0);
                      function clickhandle(){
                        setCount(++count);
                      }
                      return (
                        
                          {count}
                          +1
                        
                      );
                    }
                    export default App;
                    
                    • 声明多个 state 状态
                      import { useState } from 'react';
                      function App(props) {
                        let [age, setAge] = useState(18);
                        const [fruit, setFruit] = useState('banana');
                        const [todos, setTodos] = useState([{ text: '学习 Hook' }]);
                        function clickhandle(){
                          setAge(++age);
                        }
                        return (
                          
                            年龄:{age}
                            水果:{fruit}
                            待办事项:{todos[0].text}
                            +1
                          
                        );
                      }
                      export default App;
                      

                      useEffect 包含以下知识点:

                      • 副作用的概念

                        • 纯函数:一个确切的参数在函数运行结束,可以得到一个确切的值,例如下面的例子:
                          function test(x){
                            return x * 2;
                          }
                          x => 2 ===> 4
                          x => 3 ===> 6
                          
                          • 如果一个函数中,存在副作用,那么我们就称该函数不是一个纯函数,所谓副作用,就是指函数的结果是不可控,不可预期。
                          • 常见的副作用有发送网络请求、添加一些监听的注册和取消注册,手动修改 DOM,以前我们是将这些副作用写在生命周期钩子函数里面,现在就可以书写在 useEffect 这个 Hook 里面
                          • 基本使用

                            import { useState, useEffect } from 'react';
                            function App() {
                              let [count, setCount] = useState(0);
                              useEffect(()=>{
                                // 书写你要执行的副作用,会在组件渲染完成后执行
                                document.title = `你点击了${count}次`;
                              });
                              function clickhandle() {
                                setCount(++count);
                              }
                              return (
                                
                                  你点击了{count}次
                                  +1
                                
                              );
                            }
                            export default App;
                            
                            • 执行清理工作
                              import { useState, useEffect } from 'react';
                              function App() {
                                let [count, setCount] = useState(0);
                                useEffect(()=>{
                                  // 书写你要执行的副作用,会在组件渲染完成后执行
                                  const stopTimer = setInterval(()=>{
                                    console.log("Hello");
                                  },1000)   
                                  // console.log("副作用函数执行了");
                                  // 在 useEffect 中,可以返回一个函数,该函数我们称之为清理函数(一般就是做一些清理操作)
                                  // 该函数会在下一次渲染之后,但是在执行副作用操作之前执行
                                  return ()=>{
                                    // console.log("清理函数执行了");
                                    clearInterval(stopTimer);
                                  }
                                });
                                function clickhandle() {
                                  setCount(++count);
                                }
                                return (
                                  
                                    你点击了{count}次
                                    +1
                                  
                                );
                              }
                              export default App;
                              
                              • 副作用的依赖

                                • 目前,我们的副作用函数,每次重新渲染后,都会重新执行,有些时候我们是需要设置依赖项,传递第二个参数,第二个参数为一个依赖数组
                                  import { useState, useEffect } from 'react';
                                  function App() {
                                    let [count1, setCount1] = useState(0);
                                    let [count2, setCount2] = useState(0);
                                    let [count3, setCount3] = useState(0);
                                    useEffect(()=>{
                                      console.log("执行副作用函数");
                                    },[count1]);
                                    return (
                                      
                                        count1:{count1}
                                        count2:{count2}
                                        count3:{count3}
                                        setCount1(++count1)}>+1
                                        setCount2(++count2)}>+1
                                        setCount3(++count3)}>+1
                                      
                                    );
                                  }
                                  export default App;
                                  
                                  • 如果想要副作用只执行一次,传递第二个参数为一个空数组
                                    useEffect(()=>{
                                      console.log("执行副作用函数");
                                    },[]);
                                    

                                    自定义 Hook

                                    除了使用官方内置的 Hook,我们还可以自定义 Hook,自定义 Hook 的本质其实就是函数,但是和普通函数还是有一些区别,主要体现在以下两个点:

                                    • 自定义 Hook 能够调用诸如 useStateuseRef 等,普通函数则不能。由此可以通过内置的 Hooks 获得 Fiber 的访问方式,可以实现在组件级别存储数据的方案等。
                                    • 自定义 Hooks 需要以 use 开头,普通函数则没有这个限制。使用 use 开头并不是一个语法或者一个强制性的方案,更像是一个约定。

                                      App.jsx

                                      import { useState } from 'react';
                                      import useMyBook from "./useMyBook"
                                      function App() {
                                        const {bookName, setBookName} = useMyBook();
                                        const [value, setValue] = useState("");
                                        function changeHandle(e){
                                          setValue(e.target.value);
                                        }
                                        function clickHandle(){
                                          setBookName(value);
                                        }
                                        return (
                                          
                                            {bookName}
                                            
                                            确定
                                          
                                        )
                                        
                                      }
                                      export default App;
                                      

                                      useMyBook

                                      import { useState } from "react";
                                      function useMyBook(){
                                          const [bookName, setBookName] = useState("React 学习");
                                          return {
                                              bookName, setBookName
                                          }
                                      }
                                      export default useMyBook;
                                      
VPS购买请点击我

免责声明:我们致力于保护作者版权,注重分享,被刊用文章因无法核实真实出处,未能及时与作者取得联系,或有版权异议的,请联系管理员,我们会立即处理! 部分文章是来自自研大数据AI进行生成,内容摘自(百度百科,百度知道,头条百科,中国民法典,刑法,牛津词典,新华词典,汉语词典,国家院校,科普平台)等数据,内容仅供学习参考,不准确地方联系删除处理! 图片声明:本站部分配图来自人工智能系统AI生成,觅知网授权图片,PxHere摄影无版权图库和百度,360,搜狗等多加搜索引擎自动关键词搜索配图,如有侵权的图片,请第一时间联系我们,邮箱:ciyunidc@ciyunshuju.com。本站只作为美观性配图使用,无任何非法侵犯第三方意图,一切解释权归图片著作权方,本站不承担任何责任。如有恶意碰瓷者,必当奉陪到底严惩不贷!

目录[+]