react-17-hook-基础

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

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总结




相关文章
|
8月前
|
前端开发
React-Hooks-自定义Hook
React-Hooks-自定义Hook
33 0
|
10月前
|
缓存 前端开发
【说说你对react hook的理解】
【说说你对react hook的理解】
|
存储 缓存 JavaScript
react-hooks如何使用?
彻底弄清楚 react-hooks 如何使用
|
11月前
|
缓存 前端开发 Serverless
|
11月前
|
前端开发
|
前端开发
React自定义Hook
React自定义Hook
83 0
|
前端开发 JavaScript API
react Hook学习笔记
react Hook学习笔记
|
前端开发
react 之 HOOK 简介
hook 是啥,中文翻译叫做 钩子, 用来增强函数组件的功能,因为函数组件是在react16.8以前是没有状态的,但是函数组件又比较纯粹和简单(使用上),所以react 应社区和自身考虑,设计了hook来增强函数组件。但是在未来官方好像要让hook 和 class 共存。 相反,我们开始在新的代码中同时使用 Hook 和 class。
react 之 HOOK 简介
|
JavaScript 前端开发
react 进阶hook 之 useLayoutEffect hook
useLayoutEffect 其函数签名与 useEffect相同,但它会在所有的 DOM 变更之后同步调用 effect。可以使用它来读取 DOM 布局并同步触发重渲染
react 进阶hook 之 useLayoutEffect hook
|
前端开发
react 进阶hook 之 useImperativeHandle hook
这个hook比较简单,作用: 获取函数组件里面的事件,我们通过 ref 来获取类组件的事件,所以 这个 useImperativeHandle Hook 一般是于 ref 转发一起使用。
react 进阶hook 之 useImperativeHandle hook