升级antd版本遇到的小坑与解决办法

654 阅读1分钟

痛点

编写组件时,对于Memu组件遍历因为其会进行二次重渲染,导致即使设置key值也会被系统重置为index或者null报错,查看文档在antd@4.20.0已经对其Item组件进行废除,使用最新的传入items进行替代。于是想尝试进行升级antd版本到4.23.0稳定版本。

升级过程

执行yarn upgrade antd@4.23.

更新后发现对于引用的Button、Input组件报错如下。

# JSX element type does not have any construct or call signatures的TS类型报错。

百度后解决方案将tsconfig中加入"allowSyntheticDefaultImports": true然后更新React版本到18。

相关文章阅读:

接着就是对旧的不支持组件进行替换。

例如:

  • Modal,ToolTip、Popconfirm原有的visible替换成了open,onVisiableChange变成了onOpenChange。
  • Menu、Tabs中的children(Memu.Item,Tabs.TabPane)都替换词了items进行数组传入。类型如{key: string, label: JSX.Element}

解决完antd组件更新后。继续发现报错如下:

BigInt and JSON.stringify/JSON.parse

解决方法:对JSON.stringify进行兼容处理

const json = JSON.stringify(data, (key, value) =>
  typeof value === "bigint" ? value.toString() + "n" : value
);

相关文章阅读:https://dev.to/benlesh/bigint-and-json-stringify-json-parse-2m8p

接着就是在使用useEffect发送请求时可能内存泄露

可以使用布尔值进行预防

const [value, setValue] = useState('checking value...');
useEffect(() => {
let isMounted = true;
fetchValue().then(() => {
      if(isMounted ){
      setValue("done!"); // no more error
      } 
    });
   return () => {
    isMounted = false;
    };
}, []);

或者编写 useStateIfMounted hook

export const useIsMountedRef = () => {
    const isMounted = useRef<boolean>(false);
    useEffect(() => {
        isMounted.current = true;

        return () => {
            isMounted.current = false;
        };
    }, []

    );
    return isMounted;
};

export default function useStateIfMounted<T = any>(initialValue: T) {
    const [state, setState] = useState<T>(initialValue);
    const isMounted = useIsMountedRef();

    const newSetState = useCallback(value => {
        if (isMounted.current) {
            setState(value);
        }
    }, []
    );
    return [state, newSetState];
}


文章阅读:https://www.loginradius.com/blog/engineering/how-to-fix-memory-leaks-in-react/