美文网首页
react学习第四篇:HOC和自定义hook

react学习第四篇:HOC和自定义hook

作者: 云鹤道人张业斌 | 来源:发表于2021-06-06 11:29 被阅读0次

    概念:HOC参数为组件,返回值为新组件的函数,通过组件嵌套给子组件添加了更多功能

    作用:1. 代码提取,组件复用。2.劫持被处理组件的生命周期

    第一项:原逻辑

    import React, {useContext} from "react";
    import { appSetStateContext} from '../AppState'
    
    export interface RobotProps {
      id: number;
      name: string;
      email: string;
    }
    
    // 组件传递数据使用的是props,接口定义传入的参数类型
    
    const Robot: React.FC<RobotProps> = ({ id, name, email }) => {
      const setState = useContext(appSetStateContext)
    
      const addToCart = () => {
        if (setState) {
          setState(state => {
            return {
              ...state,
               shoppingCart: {
                 items: [
                  ...state.shoppingCart.items,
                   {id, name}
                 ]
               }
            }
          })
        }
      }
      return (
        <li>
            <button onClick={addToCart}>加入购物车</button>
          </li>
      );
    };
    
    export default Robot;
    
    // FC functional component 函数式组件。FC默认有p = {}参数也就是props
    
    

    第二项: 抽离业务代码之后

    import React from "react";
    1. 引入HOC
    import {widthAddToCart} from './AddToCart'
    
    2. 导出props的接口类型,HOC要用
    export interface RobotProps {
      id: number;
      name: string;
      email: string;
    //addToCart 是在HOC中新增的prop,这里要使用可选链标识不是必传的
      addToCart?: (id: number, name: string) => void
    }
    
    const Robot: React.FC<RobotProps> = ({ id, name, email, addToCart }) => {
      return (
        <li>
    3. 通过props传过来的执行函数,执行并传入参数id,name
    //由于props里面对addToCart使用了可选链,这里会提示addToCart可能是undefined,所以判断一下子
            <button onClick={() => addToCart && addToCart(id, name)}>加入购物车</button>
          </li>
      );
    };
    4. 使用HOC包裹组件
    export default widthAddToCart(Robot);
    

    新建AddToCart文件

    // AddToCart.tsx
    import React, {useContext} from 'react'
    import {appSetStateContext} from '../AppState'
    1. 引入组件的props的类型定义
    import {RobotProps} from './Robot'
    
    
    规范:一般使用width开头
    2. 类型RobotProps给到ChildComponent
    export const widthAddToCart = (ChildComponent: React.ComponentType<RobotProps>) => {
      // 返回类组件  return class extends React.Component {}
      // 或者返回函数式组件
      return (props:RobotProps) => {
        const setState = useContext(appSetStateContext)
      
        const addToCart = (id:number, name:string) => {
          if (setState) {
            setState(state => {
              return {
                ...state,
                 shoppingCart: {
                   items: [
                    ...state.shoppingCart.items,
                     {id, name}
                   ]
                 }
              }
            })
          }
        }
      3. 将逻辑执行函数addToCart,通过导出组件的props传递出去
          return <ChildComponent {...props} addToCart={addToCart}/>
      }
    }
    
    

    自定义hook

    1. hook是函数
    2. 命名以use 开头
    3. 内部可以调用其他hook函数
    4. 并非React的特性
    使用自定义hook实现代码的提取,实现复用

    相对于使用HOC提取共用代码,自定义hook的优势:代码清晰简洁,hook是纯函数,代码更易维护

    // AddToCart.tsx
    将widthAddCart 改成 useAddToCart 
    hook不需要引入React
    import  {useContext} from 'react'
    import {appSetStateContext} from '../AppState'
    
    export const useAddToCart = () => {
      const setState = useContext(appSetStateContext)
      
        const addToCart = (id:number, name:string) => {
          if (setState) {
            setState(state => {
              return {
                ...state,
                 shoppingCart: {
                   items: [
                    ...state.shoppingCart.items,
                     {id, name}
                   ]
                 }
              }
            })
          }
        }
        return addToCart
    }
    

    在组件中使用useAddToCart ,就比HOC更加简单

    import {useAddToCart} from './AddToCart'
    
    const Robot: React.FC<RobotProps> = ({ id, name, email }) => {
      const addToCart = useAddToCart()
      return (
        <li>
            <button onClick={() => addToCart(id, name)}>加入购物车</button>
          </li>
      );
    };
    

    相关文章

      网友评论

          本文标题:react学习第四篇:HOC和自定义hook

          本文链接:https://www.haomeiwen.com/subject/imtgsltx.html