其他分享
首页 > 其他分享> > 开发中常用的Hook

开发中常用的Hook

作者:互联网

开发中常用的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