react-17-hook-基础

1. 前言

what Hook

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


2. why

之前的组件形式缺点

  1. 函数组件一般是无状态组件
  2. 类组件可以有状态,也可以无状态
  3. 组件之间复用状态逻辑很难,组件维护越来越复杂
  4. class组件中的 this难以理解

3. Hook 基本概念

现在的函数组件也可以是有状态的组件,内部也可以维护自身的状态以及做一些逻辑方面的处理

  1. 避免地狱式嵌套,可读性提高
  2. 函数式组件,比class组件更容易理解
  3. UI和逻辑更容易分离
  4. 基本不需要 this

4. 引入hook之前的代码问题

简单的计数器案例

   function MyCom(){
            let count = 0
            function add(){
                count ++
                console.log(count)
            }
            return (
                <div>
                    {count}
                    <button onClick={add}>点我</button>
                </div>
            )
        }
        
        ReactDOM.render(
            <MyCom/>,
            document.getElementById("app")
        )

点击按钮界面变量不跟着变


5. Hooks 有哪些常用的API

Hooks让我们的函数组件拥有了类组件的特性,例如组件内的状态、生命周期

1.useState 组件内的状态
2.useEffect 生命周期
3.其他


6. 语法-State

const [state,setState] = useState(initialState)

1.state为变量
2.initialState state变量的初始值

3.setState 修改state值的方法
4.setState异步执行


7.hook -useState

包含--基本类型写法
包含--引用类型写法

  function MyCom(){
// 声明一个叫 count 的state变量,  初始值为0
            let [count, setCount] = React.useState(0)
// 声明一个 叫obj的 state变量 初始值为空对象
            let [obj, setObj] = React.useState({})
            function add(){
// 基本类型的修改
                setCount(++count)
// 引用类型的修改
                setObj({
                    name: 'a'+count
                })
                console.log(count)
            }
            return (
                <div>
                    {count}-{obj.name}
                    <button onClick={add}>点我</button>
                </div>
            )
        }
        

在函数组件中通过useState实现函数内部维护state,参数为state默认的值,返回值是一个数组,
第一个值为当前的state
第二个值为更新state的函数


8 类组件 VS 函数式组件

1.state声明方式:
在函数组件中通过useState 直接获取,类组件通过constructor构造函数中设置

2.state读取方式:
在函数组件中直接使用变量,类组件通过this.state.count的方式获取

3.state更新方式:
在函数组件中通过setCount更新,类组件通过this.setState()

总结就是useState使用起来更为简洁,减少了this指向不明确的情况


9. hook-钩子 -useEffect

9.1语法

React.useEffect(参数1,参数2)
参数1 是回调函数
参数2 是参数1 这个函数监听的变量


9.2 useEffect 相当于3个钩子的综合

1.componentDidMount
2.componentDidUpdate
3.componentWillUnMount


9.3 分析

参数2 为空 不写: DidMount+DidUpdate
在第一次渲染和更新之后都会执行


参数2 空数组[] ,DidMount
第一次渲染后


参数2 [变量], 监听变量的改变 componentDidUpdate
React 将对前一次渲染的变量值count和后一次渲染的 count 值进行比较


9.4 代码

  function MyCom(){
            let [count, setCount] = React.useState(0)
            let [obj, setObj] = React.useState({})
            function add(){
                // setCount(++count)
                setObj({
                    name: 'a'+count
                })
                console.log(count)
            }
            React.useEffect(() => {
               console.log("初始化或更新1")
            })
            React.useEffect(() => {
               console.log("初始化2")
            }, [])
            React.useEffect(() => {
               console.log("初始化或count更新3")
            }, [count,obj])
            return (
                <div>
                    {count}-{obj.name}
                    <button onClick={add}>点我</button>
                </div>
            )
        }

这个建议 还是自己写写,因为代码本身也很简单


10. 清除函数

回调函数中可以返回一个清除函数,这是effect可选的清除机制,相当于类组件中componentwillUnmount生命周期函数,可做一些清除副作用的操作,比如定时器

    // 创建响应数据以及修改方法
        let [num,setNum]=useState(20);
        // 会在更新之前 执行指定的销毁函数
        // 防止初始化的代码 重复绑定  定时器
        useEffect(()=>{
            console.log("useEffect")
            // 绑定定时器 让num递增
            let timer=setInterval(()=>{
                console.log("定时器");
                num++;
                setNum(num);//num发生变化
            },1000);
            return ()=>{//销毁 
                clearInterval(timer);
            }
        })

11. 总结

1.每调用useHook一次都会生成一份独立的状态
2.通过自定义hook能够更好的封装我们的功能
3.useEffect相当于componentDidMount,componentDidUpdate 和 componentWillUnmount 这三个生命周期函数的组合


12.其他hooks

useReducer
useCallback
useMemo
useRef


13. 这里再梳理个 useReducer

其实就是 useState的替代版 主要用来 结合redux 中的reducer

13.1 简单的看下 store 中 redux的结构

import { createStore } from "redux";

let  defaultState = {
    counter:0
} 
export const reducer = (state=defaultState,{type,payload=10})=>{
    switch (type){
        case "counter/incremented":{
            let tempState = JSON.parse(JSON.stringify(state));
            tempState.counter += payload
            return tempState
        }
        case "counter/decremented":{
             return{
                 ...state,
                 counter:state.counter - payload
             }
        }
        default:{
            console.log("switch  默认")
            return state
        }
    }
}

let store = createStore(reducer)
export default store

13.2 使用 useReducer

import { useState, useEffect ,useReducer} from 'react';
import {reducer} from "../store"
function HookPage() {
  const [state, dispatch] = useReducer(reducer, {counter:99})
  } 

  return (
    <div className="App">
      <h1>{state.counter}</h1>
      <button onClick={()=>{
        dispatch({type:"counter/decremented",payload:100})
      }}> redux</button>
    </div>
  );
}
export default HookPage;

13.3 分析

useReducer()
参数1: 就是reducer
参数2:就是初始值
参数3:是个初始化的回调函数


14. 完整的 组件内使用 hook

import { useState, useEffect ,useReducer} from 'react';
import {reducer} from "../store"
function HookPage() {
  let [counter, setCounter] = useState(0)
  let [person, setPerson] = useState({ name: "yzs" })

  const [state, dispatch] = useReducer(reducer, {counter:99})
  function increase(v) {
    counter += v
    setCounter(counter)
  }
  function update() {
    setPerson({
      name: "郑州"
    })
  } 
  // **************钩子
  useEffect(() => {
    console.log("初始化或者更新")
  })
  useEffect(() => {
    console.log("[]  初始化")
  },[])
  useEffect(() => {
    console.log("初始化或 对应的值变化")
  },[counter,person])

  return (
    <div className="App">

      <h1>{counter}</h1>
      <button onClick={() => {
        increase(10)
      }}>增加</button>
      <hr />
      <h1>{person.name}</h1>
      <button onClick={update}> name</button>
      <hr/>
      <h1>{state.counter}</h1>
      <button onClick={()=>{
        dispatch({type:"counter/decremented",payload:100})
      }}> redux</button>
    </div>
  );
}

export default HookPage;

15. 总结性hook

可参考这篇文章 react常用-hook总结


参考资料

react-hook-常用总结
react-hook


初心

我所有的文章都只是基于入门,初步的了解;是自己的知识体系梳理;
如果能帮助到有缘人,非常的荣幸,一切为了部落的崛起;
共勉
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

相关阅读更多精彩内容

  • Hook 是 react 16.8 推出的新特性,具有如下优点:Hook 使你在无需修改组件结构的情况下复用状态逻...
    林木木road阅读 4,198评论 0 1
  • 一、React介绍 温馨提醒:想要获取更好的观看效果,可以点击查看本篇文章的原文档(React-Hook快速入门(...
    SwiftBirds阅读 3,635评论 0 1
  • 前言 自react16.8发布了正式版hook用法以来,我们公司组件的写法逐渐由class向函数式组件+hook的...
    大春春阅读 9,558评论 3 7
  • Tip: hook使用规则: 1.只能在函数最外层调用 Hook。不要在循环、条件判断或者子函数中调用 2.只能在...
    Calvin_Wu0720阅读 1,765评论 0 0
  • 函数式组件在不编写class的情况下使用state以及其他的React特性(比如生命周期) 一、Hooks结合函数...
    諾城阅读 4,840评论 2 0

友情链接更多精彩内容