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


初心

我所有的文章都只是基于入门,初步的了解;是自己的知识体系梳理;
如果能帮助到有缘人,非常的荣幸,一切为了部落的崛起;
共勉
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 213,928评论 6 493
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 91,192评论 3 387
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 159,468评论 0 349
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 57,186评论 1 286
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 66,295评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,374评论 1 292
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,403评论 3 412
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,186评论 0 269
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,610评论 1 306
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,906评论 2 328
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,075评论 1 341
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,755评论 4 337
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,393评论 3 320
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,079评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,313评论 1 267
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,934评论 2 365
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,963评论 2 351

推荐阅读更多精彩内容

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