1.什么是Hook?

  • Hook 是 React 16.8 的新增特性,
    它可以让函数式组件拥有类组件特性

2. 使用hooks 理由:


  1. 高阶组件为了复用,导致代码层级复杂
  2. 生命周期的复杂
  3. 写成 function函数组件 ,无状态组件, 因为需要状态,又改成了class,成本高 ```
  • 在Hook出现之前, 如果我们想在组件中保存自己的状态, 如果我们想在组件的某个生命周期中做一些事情, 那么我们必须使用类组件
    • 但是类组件的学习成本是比较高的, 你必须懂得ES6的class, 你必须懂得箭头函数
    • 但是在类组件的同一个生命周期方法中, 我们可能会编写很多不同的业务逻辑代码 这样就导致了大量不同的业务逻辑代码混杂到一个方法中, 导致代码变得很难以维护 (诸如: 在组件被挂载的生命周期中, 可能主要注册监听, 可能需要发送网络请求等)
    • 但是在类组件中共享数据是非常繁琐的, 需要借助Context或者Redux等
  • 所以当应用程序变得复杂时, 类组件就会变得非常复杂, 非常难以维护
  • 所以Hook就是为了解决以上问题而生的 ```

    3.如何使用 hooks

  • Hook的使用我们无需额外安装任何第三方库, 因为它就是React的一部分

  • Hook只能在函数组件中使用, 不能在类组件,或者函数组件之外的地方使用
  • Hook只能在函数最外层调用, 不要在循环、条件判断或者子函数中调用

useState(保存组件状态)

  1. const [state, setState] = useState(initialState)
  2. const [ageState, setAgeState] = useState(18);
  3. function incrementAge() {
  4. // setAgeState(ageState + 10);
  5. // setAgeState(ageState + 10);
  6. // setAgeState(ageState + 10);
  7. setAgeState((preAgeState)=>preAgeState + 10);
  8. }
  9. <p>{ageState}</p>
  10. <button onClick={()=>{incrementAge()}}>增加</button>


useEffect(处理副作用)和 useLayoutEffect (同步执行副作用)

1.什么是 useEffect hooks?

  • 可以把 useEffect 看作 componentDidMount, componentDidUpdate 和 componentWillUnmount 这三个生命周期的组合

    2.useEffect Hook特点?

  • 可以设置依赖, 只有依赖发生变化的时候才执行 ``` useEffect(() => { //effect return () => { // cleanup } }, [依赖的状态;空数组,表示不依赖])

useEffect(()=>{ // componentDidMount // componentDidUpdate console.log(‘组件被挂载或者组件更新完成’); return ()=>{ // componentWillUnmount console.log(‘组件即将被卸载’); }

  1. });
  2. -----------------------
  3. useEffect(()=>{
  4. // 组件被挂载
  5. console.log('修改DOM');
  6. });
  7. useEffect(()=>{
  8. // 组件被挂载
  9. console.log('注册监听');
  10. return ()=>{
  11. console.log('移出监听');
  12. }
  13. });
  14. useEffect(()=>{
  15. console.log('发送网络请求');
  16. });
  1. **不要对 Dependencies 撒谎,如果你明明使用了某个变量,却没有申明在依赖中,你等于向react撒了谎,后果就是,当依赖的变量改变时,useEffect 也不会再次执行 eslint会报警告**
  2. <a name="NIWSm"></a>
  3. #### useEffect 和 useLayoutEffect 的区别
  4. ```javascript
  5. 区别是 useLayouEffect 是同步执行, 会在DOM 更新完成后立即执行,但是会在浏览器进行任何绘制之前运行完成,阻塞了浏览器的绘制,跟class写法的componentDidMount
  6. 和componentDidUpdate(render之后,立即执行)类似,都是同步,
  7. useEffect 是异步,不会block,browser, painting, 性能更好一点

useContext Hook

  • useContext相当于 类组件中的 static contextType = Context

    useCallback(记忆函数)

  • useCallback用于优化代码, 可以让对应的函数只有在依赖发生变化时才重新定义

  • 防止因为组件重新渲染,导致方法被重创建,起到缓存作用,只有第二个参数 变化了,才重新声明一次 ```javascript var handleClick = useCallback( () =>{ console.log(name) }, [name])

//只有name改变后, 这个函数才会重新声明一次 //如果传入空数组, 那么就是第一次创建后就被缓存,如果name 后期改变了,拿到的还是老的name //如果不传第二个参数,每次都会重新声明一次,拿到的就是最新的name

  1. <a name="nvcyd"></a>
  2. #### useMemo Hook
  3. - useMemo用于优化代码, 可以让对应的函数只有在依赖发生变化时才返回新的值
  1. // 以下代码的作用: 只要countState没有发生变化, 那么useCallback返回的永远都是同一个函数
  2. /*
  3. function useCallback(fn, arr){
  4. return useMemo(()=>{
  5. return fn;
  6. }, arr);
  7. }
  8. -----------------
  9. const decrement = useCallback(()=>{
  10. setCountState(countState - 1);
  11. }, [countState]);
  12. -----------------

// 以下代码的作用: 只要countState没有发生变化, 那么useMemo返回的永远都是同一个值 const decrement = useMemo(()=>{ return ()=>{ setCountState(countState - 1); }; }, [countState]);

  1. <a name="F6qAI"></a>
  2. #### useRef (保存引用值)
  3. ```javascript
  4. const myswiper = useRef(null);
  5. <Swiper ref = {myswiper} />

useReducer 和 useContext(减少组件层级)

  1. import React from 'react'
  2. var GlobalConter = React.createContext()
  3. //注意 此时的 reducer 返回值是一个对象 {isShow: false . list: []}
  4. function App(props) {
  5. let [] = useReducer(reducer, { isShow: true, list: [] })
  6. return <GlobalContext.Provider value={(
  7. dispatch
  8. )}>
  9. <div>
  10. { state.isShow? <div >我是选项卡</div> :null }
  11. {props.children}
  12. </div>
  13. </GlobalContext.Provider> }
  14. }
  15. function Detail(){
  16. var {dispatch} = useContext(GlobalContext)
  17. useEffect(() => {
  18. //隐藏 dispatch({
  19. type:"Hide",
  20. payload:false
  21. })return () => {
  22. //显示 dispatch({
  23. type:"Show",
  24. payload:true })
  25. };
  26. }, [])
  27. return <div>
  28. detail
  29. </div>
  30. }

redux-react-hook 无缝使用原来的 redux,和中间件 promise,thunk,saga

自定义 hooks
image.png

image.png