开发中常用的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 进行多级组件传递数据
用法:
createContext
Provider
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