近期项目知识盲区总结(ref+滚动条样式)

151 阅读2分钟
一、项目背景

本项目使用 umi + react + antd 搭建,react 内部使用函数组件书写。

二、需要解决的问题及解决方案
  1. 父组件调用子组件内的方法:父组件若想调用子组件内的方法需使用 ref,但父组件是函数组件,因此不能使用 CreateRef 方法创建 ref,需要使用 Hooks 中的 useRef 方法创建 ref。代码如下:
    // 父组件代码
    import { useRef } from "react"; 
    import SonComponent from "./SonComponent";
    
    export default function ParentComponent () {
        const showRef = useRef;
        const handleClick = () => {
            // 先判断 showRef.current 是否存在,如果不判断直接调用子组件方法会报错
            if (showRef.current) {
                // 调用子组件方法,showPanel 为子组件内方法
                showRef.current.showPanel();
            };
        };
        return (
            <div>
                <button onClick={ handleClick }>点击调用子组件方法</button>
                <SonComponent ref={showRef} />
            </div>
        )
    };

子组件为函数组件,将子组件内的方法暴露出来需要调用 forwardRef 方法和 useImperativeHandle 方法。代码如下:

    // 子组件代码
     import { forwardRef, useImperativeHandle } from "react";
     function SonComponent (props, ref) {
        const {} = props;
        const showPanel = () => {
            console.log('子组件方法')
        };
        useImperativeHandle(ref, () => ({
            showPanel,
        }));
        return (
            <div>
                // 子组件内容
            </div>
        );
    };
    export default forwardRef(SonComponent);

但如果子组件内已经调用了 connect 方法,此时 connect 如果包裹 forwardRef 的话,那么子组件中的方法无法暴露到父组件,会导致父组件无法调用子组件中的方法,应让 forwardRef 方法包裹 connect 方法。代码如下:

    // 父组件代码不变
    // 子组件代码
    import { useEffect, useState, forwardRef, useImperativeHandle } from "react";
    import { connect } from "dva";
    let SonComponent = (props: any) => {
      const { refInstance } = props;
      const showPanel = () => {
            console.log('子组件方法')
        };

      useImperativeHandle(refInstance, () => ({
        showPanel,
      }));
      return (
          <div>
            // 子组件内容
          </div>
      );
    };
    const mapStateToProps = (state: any) => ({});
    SonComponent = connect(mapStateToProps)(SonComponent);
    // 此处使用 refInstance 替代 ref 避免与 ref 重名(百度的,我不懂为啥,没做尝试)
    export default forwardRef((props, ref) => (
      <SonComponent {...props} refInstance={ref} />
    ));
  1. 滚动条样式修改:客户要求无论多少条列表内容全部显示,但又不能有滚动条,我不知道怎么在滚动条去掉的同时保留滚动条的功能,于是我选择把滚动条变窄。代码如下:
    // css 文件
    .showList {
      min-height: 50px;
      max-height: 350px;
      overflow-y: scroll;
    }
    .showList::-webkit-scrollbar {
      width: 5px;
    }