ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

开发中常用的Hook

2022-04-10 00:05:17  阅读:188  来源: 互联网

标签:count 常用 const setCount Hook state 开发 useState return


开发中常用的Hook

什么是Hook?

Hook 是一些可以让你在函数组件里“钩入” React state 及生命周期等特性的函数,用来实现一些 class 组件的特性的。

 1  // 引入 React 中的 useState Hook。它让我们在函数组件中存储内部 state。
 2  import React, { useState } from 'react';
 3  ​
 4  function Example() {
 5  // 声明一个叫 “count” 的 state 变量。
 6  //useState 就是一个 Hook 
 7  //当前状态和一个让你更新它的函数
 8  //useState( ) 括号里面是count 的初始值
 9  const [count, setCount] = useState(0);
10  return (
11   <div>
12     <p>You clicked {count} times</p>
13     <button onClick={() => setCount(count + 1)}>
14       Click me
15     </button>
16   </div>
17  );
18  }

Hook 不能在 class 组件中使用

class 组件比较重量级 -- 开发和维护有一定的难度,后来使用 函数组件,比较轻量,但是没有 calss的特性(state),需要使用一些别的方式来弥补 --> Hooks

【官网相关链接】

EffectHook(副作用Hook)

副作用 hook 用来处理一些React之外的事件,比如ajax请求

但是其实 EffectHook 最常见的使用场景是 模拟 生命周期

用法:当useEffect依赖的数据发生变化,就会调用回调函数

useEffect(回调函数, [依赖的数据]);

格式 : 

useEffect(当依赖发生变化时调用的函数, [依赖的数据]);

  

 1  //需求:监视count
 2  //引入副作用钩子函数
 3  import React, { useEffect } from "react";
 4  ​
 5  export default function EffectHook() {
 6      
 7    const [count, setCount] = useState(0);
 8      
 9    //count作为EffectHook的依赖,所以只要count发生了变化,就会触发这个回调的调用。
10    useEffect(() => {
11      console.log("EffectHook调用了");
12    },[count]);
13      
14    const onClick = () => {
15      setCount(count + 1);
16    };
17      
18    return (
19      <div>
20        <p>Count:{count}</p>
21        <p>Double:{double}</p>
22        <button onClick={onClick}>++</button>
23      </div>
24    );
25  }

 

使用EffectHook模拟生命周期:
a.模拟componentDidMount
 useEffect(() => {
     console.log("这是用来模拟挂载期的");
 }, []);

 

b.模拟componentDidUpdate
 useEffect(() => {
     console.log("这是用来模拟更新期的");
 }, [deps]);

 

c.模拟componentWillUnmount
 useEffect(() => {
     return ()=>{
         // 在这里面写卸载期的代码
         console.log("这是用来模拟卸载期的");
     }
 }, []);

 

注意:

同个useEffect下,在检测销毁和检测字段更新之间,只能二选一。留下空数组,可以检测到return中的销毁。数组非空时,视图更新会带动return返回值,因此如果要检测字段更新,就无法检测销毁。

StateHook

这是一个react提供好的用于实现state响应式特性的hook,使用如下:

 1  export default function StateHook() {
 2    // 调用useState得到一个数组,顺便解构出来两个东西,一个是数据,一个是用于操作数据的函数
 3    const [count, setCount] = useState(0);
 4    const onClick = () => {
 5      // 调用对应的方法操作数据
 6      setCount(count + 1);
 7    };
 8    return (
 9      <div>
10        {/* 直接渲染对应的数据 */}
11        <p>Count:{count}</p>
12        <button onClick={onClick}>增加</button>
13      </div>
14    );
15  }

 

值得注意的是,hook只能使用在函数的最外层,任何别的位置都会报错。

声明多个 state 变量

你可以在一个组件中多次使用 State Hook

1  function ExampleWithManyStates() {
2    // 声明多个 state 变量!
3    const [age, setAge] = useState(42);
4    const [fruit, setFruit] = useState('banana');
5    const [todos, setTodos] = useState([{ text: 'Learn Hooks' }]);
6    // ...
7  }

 

自定义Hook

使用hook可以让我们的数据的操作数据的逻辑放在一起,并且可以实现封装,把代码整理地更加易于维护。

如果在操作数据的过程中有一些比较复杂的逻辑,我们就可以采用自定义hook的方式把这部分逻辑分离出来。

 1  export default function StateHook() {
 2    const [count, setCount] = useState(0);
 3    const onClick = () => {
 4      // 如果有更加复杂的逻辑(假装很复杂)
 5      let val = 0;
 6      if (count > 0) {
 7        val = count - 1;
 8      } else {
 9        val = count + Math.floor(Math.random() * 10);
10      }
11      setCount(val);
12    };
13    return (
14      <div>
15        <p>Count:{count}</p>
16        <button onClick={onClick}>增加</button>
17      </div>
18    );
19  }

 

如果我们在页面里面有大量的复杂逻辑,这样同样会使代码变得非常杂乱,后期难以维护,于是我们可以这样写。

 1  // 自定义hook要求以use开头
 2  function useCount(initValue = 0) {
 3    const [count, setCount] = useState(initValue);
 4    const fn = () => {
 5      let val = 0;
 6      if (count > 0) {
 7        val = count - 1;
 8      } else {
 9        val = count + Math.floor(Math.random() * 10);
10      }
11      setCount(val);
12    };
13    return [count, fn];
14  }
15  export default function StateHook() {
16    // 调用我们自定义的hook , 把复杂的逻辑全抽离到自定义hook,这样在我们的组件里面就尽可能简洁了
17    const [count, setCount] = useCount();
18    const onClick = () => {
19      setCount();
20    };
21    return (
22      <div>
23        <p>Count:{count}</p>
24        <button onClick={onClick}>增加</button>
25      </div>
26    );
27  }

 

ContextHook

使用 useContext 使用context 进行多级组件传递数据

用法:

  1. createContext

  1. Provider

  1. useContext

const Provider给的value = useContext(在第1步创建的context);

ContextHook基本使用步骤如下:

a.调用createContext创建一个Context对象
 const MyContext = createContext();

 

b.使用Provider组件提供一个“全局”数据
 1  export default function ContextHook() {
 2    const [count, setCount] = useState(10);
 3    const add = (val) => {
 4      setCount(count + val);
 5    };
 6    return (
 7      <MyContext.Provider value={{ count, add }}>
 8        <Parent />
 9      </MyContext.Provider>
10    );
11  }

 

c.在后代组件里面使用useContext方法获取Context对象
 1  function Parent() {
 2    return (
 3      <div>
 4        <Child />
 5      </div>
 6    );
 7  }
 8  function Child() {
 9    const context = useContext(MyContext);
10    return (
11      <div>
12        {/* context对象就是之前的Provider里面的value属性 */}
13        <p>count from ancestors:{context.count}</p>
14        <button onClick={() => context.add(1)}>Add</button>
15      </div>
16    );
17  }
18  import React, { createContext, useContext, useState } from "react";
19  // 1. 创建一个context
20  const MyContext = createContext();
21  ​
22  export default function ContextStudy() {
23    const [count, setCount] = useState(5);
24    const add = () => {
25      setCount(count + 1);
26    };
27    // 2. 需要一个Provider
28    return (
29      <MyContext.Provider value={{ count, add }}>
30        <Parent />
31      </MyContext.Provider>
32    );
33  }
34  ​
35  function Parent() {
36    return <Child />;
37  }
38  ​
39  function Child() {
40    const data = useContext(MyContext);
41    console.log(data);
42    return (
43      <div>
44        <h3>孙子</h3>
45        <p>{data.count}</p>
46        <button onClick={data.add}>++</button>
47      </div>
48    );
49  }

 

RefHook

在函数组件里面我们可以使用userRef这个Hook获取一个元素或者组件的引用

 1  import React, { useEffect, useRef } from "react";
 2  ​
 3  export default function RefHook() {
 4    const btn = useRef();
 5    // 在componentDidMount后获取
 6    useEffect(() => {
 7      console.log(btn.current);
 8    }, []);
 9    return (
10      <div>
11        <button ref={btn}>Button</button>
12      </div>
13    );
14  }

 

ReducerHook

useReducer是useState的替代方案,当useState里面的逻辑相对复杂的时候,我们可以使用useReducer来代替。

useRducer的基本使用步骤如下:

a.准备一个初始state数据和操作state的方法
 1  // 初始state
 2  const state = {
 3    count: 0,
 4  };
 5  // 操作state的方法reducer
 6  // aciont里面一般是type和pyload两个属性用来判断不同的复杂逻辑
 7  const reducer = (st = state, action) => {
 8    const state = JSON.parse(JSON.stringify(st));
 9    // 通过判断不同的action来处理不同的逻辑
10    switch (action.type) {
11      case "add":
12        state.count += action.pyload;
13        break;
14      case "reduce":
15        state.count -= action.pyload;
16        break;
17    }
18    // reducer一定要返回一个新的state
19    return state;
20  };

 

b.调用useReducer这个Hook来得到state和dispatch
 export default function ReducerHook() {
   // state就是我们需要维护的数据,dispatch是一个方法,用来调用reducer的
   const [state, dispatch] = useReducer(reducer, initState);
   return (
     <div>
       <div>ReducerHook</div>
       <div>state's count : {state.count}</div>
       {/* dispatch方法传入一个action来激活reducer里面对应的操作 */}
       <button onClick={() => dispatch({ type: "add", pyload: 1 })}>Add</button>
       <button onClick={() => dispatch({ type: "reduce", pyload: 1 })}>
         reduce
       </button>
     </div>
   );
 }

 

其它Hook

上述的那些已经是我们平时比较常用的hook,当然hook不是只有这些,如果想了解,戳这里

 

练手小目标:

1.能使用useState实现函数式组件的响应式数据。

2.能使用useContext实现多级组件间的数据传递。

3.能使用useEffect模拟生命周期。

4.能使用useRef获取DOM元素的引用。

5.能使用useReducer实现响应式数据操作。

标签:count,常用,const,setCount,Hook,state,开发,useState,return
来源: https://www.cnblogs.com/Laoevil/p/16124314.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有