react18函数组件使用指南-使用代码集合以及报错记录汇总(不断更新中)

发布时间 2023-10-09 02:02:22作者: 糖~豆豆

@

目录

1. react报错-Warning: Instance created by useForm is not connected to any Form element. Forget to pass form prop?

当前使用版本

    "@designable/core": "^1.0.0-beta.45",
    "@designable/formily-antd": "^1.0.0-beta.45",
    "@designable/react-settings-form": "^1.0.0-beta.45",
    "@formily/antd": "^2.2.29",
    "@ice/runtime": "^1.0.0",
    "antd": "^4.22.8",

问题分析

当页面初始化时form对象找不到可关联的Form表单,出现上述警告,我们需要设置根据visible来设置表单

解决方案

如果是除了modal嵌套类型出现此种报错,我们可以设置如果组件并未渲染,不要调用form的实例,在外层加一个判断,return里去掉form渲染的代码

Modal中嵌套Form表单的情况解决方案

const useResetFormOnCloseModal = ({ form, visible }) => {
  const prevVisibleRef = useRef();
  useEffect(() => {
    prevVisibleRef.current = visible;
  }, [visible]);
  const prevVisible = prevVisibleRef.current;
  useEffect(() => {
    if (!visible && prevVisible) {
      form.resetFields();
    }
  }, [visible]);
};

const ModalForm = ({ visible, onCancel }) => {
  const [form] = Form.useForm();
  useResetFormOnCloseModal({
    form,
    visible,
  });

  const onOk = () => {
    form.submit();
  };

  return (
    <Modal title="Basic Drawer" visible={visible} onOk={onOk} onCancel={onCancel}>
      <Form form={form} layout="vertical" name="userForm">
        <Form.Item
          name="name"
          label="User Name"
          rules={[
            {
              required: true,
            },
          ]}
        >
          <Input />
        </Form.Item>
        <Form.Item
          name="age"
          label="User Age"
          rules={[
            {
              required: true,
            },
          ]}
        >
          <InputNumber />
        </Form.Item>
      </Form>
    </Modal>
  );
};

2.监听页面滚动事件,获取页面滚动到哪里了

解决方案

参考文档

import React, { useRef } from 'react';
import { useScroll } from 'ahooks';

export default () => {
  const ref = useRef(null);

  const scroll = useScroll(ref, (val) => val.top > 100 && val.top < 200);

  return (
    <>
      <p>{JSON.stringify(scroll)}</p>
      <div
        style={{
          height: '160px',
          width: '160px',
          border: 'solid 1px #000',
          overflow: 'scroll',
          whiteSpace: 'nowrap',
          fontSize: '36px',
        }}
        ref={ref}
      >
        <div>
          Lorem ipsum dolor sit amet, consectetur adipisicing elit. A aspernatur atque, debitis ex
          excepturi explicabo iste iure labore molestiae neque optio perspiciatis
        </div>
        <div>
          Aspernatur cupiditate, deleniti id incidunt mollitia omnis! A aspernatur assumenda
          consequuntur culpa cumque dignissimos enim eos, et fugit natus nemo nesciunt
        </div>
        <div>
          Alias aut deserunt expedita, inventore maiores minima officia porro rem. Accusamus ducimus
          magni modi mollitia nihil nisi provident
        </div>
        <div>
          Alias aut autem consequuntur doloremque esse facilis id molestiae neque officia placeat,
          quia quisquam repellendus reprehenderit.
        </div>
        <div>
          Adipisci blanditiis facere nam perspiciatis sit soluta ullam! Architecto aut blanditiis,
          consectetur corporis cum deserunt distinctio dolore eius est exercitationem
        </div>
        <div>Ab aliquid asperiores assumenda corporis cumque dolorum expedita</div>
        <div>
          Culpa cumque eveniet natus totam! Adipisci, animi at commodi delectus distinctio dolore
          earum, eum expedita facilis
        </div>
        <div>
          Quod sit, temporibus! Amet animi fugit officiis perspiciatis, quis unde. Cumque
          dignissimos distinctio, dolor eaque est fugit nisi non pariatur porro possimus, quas quasi
        </div>
      </div>
    </>
  );
};

3.React 18 + antd 5.8.6 更改主题色-定制主题(4.x修改主题配色请参考第四条)

文档在此:https://ant-design.antgroup.com/docs/react/customize-theme-cn

解决方案

碎碎念:其实使用很简单,就是用ConfigProvider包一下你的组件就行了,比4.X版本改色简单多啦~~~~

import { Button, ConfigProvider, Space } from 'antd';
import React from 'react';

const App: React.FC = () => (
  <ConfigProvider
    theme={{
      token: {
        // Seed Token,影响范围大
        colorPrimary: '#00b96b',
        borderRadius: 2,

        // 派生变量,影响范围小
        colorBgContainer: '#f6ffed',
      },
    }}
  >
    <Space>
      <Button type="primary">Primary</Button>
      <Button>Default</Button>
    </Space>
  </ConfigProvider>
);

4. React + antd 4.X 更改主题色-定制主题

解决方案-配置 less 变量文件

在项目入口的index.less引入并写入下面代码来更改主题,建立一个单独的 less 变量文件,引入这个文件覆盖 antd.less 里的变量


@import '~antd/es/style/themes/default.less';
@import '~antd/dist/antd.less'; // 引入官方提供的 less 样式入口文件
// 下面是你的自定义主题颜色
@primary-color: rgb(201, 75, 24); // primary color for all components
@link-color: rgb(201, 75, 24); // link color
@success-color: #52c41a; // success state color
@warning-color: #faad14; // warning state color
@error-color: #f5222d; // error state color
@font-size-base: 14px; // major text font size
@heading-color: rgba(0, 0, 0, 0.85); // heading text color
@text-color: rgba(0, 0, 0, 0.65); // major text color
@text-color-secondary: rgba(0, 0, 0, 0.45); // secondary text color
@disabled-color: rgba(0, 0, 0, 0.25); // disable state color
@border-radius-base: 2px; // major border radius
@border-color-base: #d9d9d9; // major border color
@box-shadow-base: 0 3px 6px -4px rgba(0, 0, 0, 0.12), 0 6px 16px 0 rgba(0, 0, 0, 0.08),
  0 9px 28px 8px rgba(0, 0, 0, 0.05); // major shadow for layers

5. React报错ResizeObserver loop completed with undelivered notifications.

ResizeObserver loop completed with undelivered notifications.
    at handleError (http://localhost:3000/js/main.js:2161:58)
    at http://localhost:3000/js/main.js:2180:7

问题分析

  • antd 的 table 组件容易报这个错误
  • 报错的原因:在页面绘制的时候,页面突然发生调整大小的事件,导致了样式和布局都需要重新评估,这个调整大小导致的布局变化,将延迟到下一帧来绘制。
  • 其他分析感兴趣的小伙伴可以自行查询,这里不做过多解释啦~~

解决方案

简单粗暴解决:所以在报错组件里面,或者全局,添加隐藏这个浮层的样式


//antd组件内 ResizeObserver loop limit exceeded报错隐藏
#webpack-dev-server-client-overlay {
  display: none !important;
}

6. React designable formily antd form designer 很多cdn.jsdelivr.net资源找不到的问题,cdn.jsdelivr.net访问报错

例如下载访问报错 npm/monaco-editor@0.36.1/min/vs/base/worker/workerMain.js

问题分析

  • jsdelivr提供免费、高速且稳定的 CDN 服务,提供了 NPM、Github、WordPress Plugin 和其他自定义网站的资源镜像,在国内使用的是网宿CDN,所以国内速度比较快,有大量的用户使用.
  • jsdelivr这是一个非常快的免费的cdn服务,所有公开的javascript npm包和github仓库,都可以使用jsdelivr来作为静态资源服务器,而且免费

解决方案1:

  • 切换到其他CDN,将cdn.jsdelivr.net域名替换为fastly.jsdelivr.net或者gcore.jsdelivr.net
  • 在designable 项目中, react-setting-form初始化时候 ,有这个函数setNpmCDNRegistry可以用来设置CDN
  • 其他项目自行设置或者替换代码即可

解决方案2:

使用国内资源库:

1.https://staticfile.org
CDN 加速由七牛云提供,技术社区掘金支持,资源库库相对也比较丰富.很多年了.
2.https://cdn.baomitu.com/
360 前端静态资源库是由奇舞团支持并维护的开源项目免费 CDN 服务,支持 HTTPS 和 HTTP/2,囊括上千个前端资源库和 Google 字体库。
3.https://cdn.bytedance.com/
字节跳动提供的提供的资源库也比较丰富
4.https://unpkg.zhimg.com
知乎提供的unpkg.com国内的镜像,访问速度快.但是疑似有些限制.

解决方案3:请参考本文第12个问题,有更多处理解决方案详解

7.React onClick事件无法传参 不管用 或者报错

Type 'void' is not assignable to type 'MouseEventHandler<HTMLSpanElement> | undefined'.ts(2322)
index.d.ts(1521, 9): The expected type comes from property 'onClick' which is declared here on type 'DetailedHTMLProps<HTMLAttributes<HTMLSpanElement>, HTMLSpanElement>'

解决方案

  <span className="tableOperationIcon" onClick={handleUpdate(_.id)}> 点击功能 </span>
  改成下面写法就可以了
  <span className="tableOperationIcon" onClick={() => {  handleUpdate(_.id); }} > 点击功能  </span>

8.React报错Property 'pathname' is missing in type '{ children: Element; }' but required in type '

解决方案1

按照规定的变量类型,声明变量

解决方案2 (不建议这么做)

声明的时候:any

解决方案3 (不建议这么做)

赋值的时候 as any

9.React报错Type '{ children: string; }' has no properties in common with type 'IntrinsicAttributes & ITextWidgetProps'.

解决方案(这个有待验证,如果没有用,请留言)

解决办法:给组件ITextWidgetProps手动加完善类型

interface ITextWidgetProps {
  children?: string;
}

10. 多种方案教你 React页面传参

方案1:使用useNavigate 和 useLocation进行页面传参

点击按钮携带参数跳转逻辑

navigate 函数options 配置选项详解如下:

  • replace:是否替换当前页面的历史记录;
  • state:传递的状态数据;
  • replace:是否替换当前页面的历史记录;
  • shoudlNavigate:是否允许进行路由跳转;
  • replace:是否替换当前页面的历史记录。

import { useNavigate } from "react-router-dom";
 const jumpTo = (name: string) =>{
        navigate('/home', { state: { name } });
    }

<Card title="XXX" onClick={() => toDetail('送你一朵小红花')}>  </Card>

注意事项: 与 history.push 不同,navigate 不会在浏览器历史记录中添加重复的路由记录。navigate({ pathname, state }) 这种写法会添加新的历史记录。

获取参数传递内容逻辑

在 React Router 中,可以通过 useLocation hook 来获取传递的参数和路径信息。

  import { useLocation } from "react-router-dom";
  const location = useLocation();
  const data = location.state;
  console.log("-----", data);

方案2 使用useNavigate 和 useSearchParams 进行页面传参

举个例子:
传递参数


import { useNavigate } from 'react-router';
const navigateTo = useNavigate();
const go = (e) => {
    navigateTo('/xiaojin?id=' + e.id);
};

获取参数


import { useSearchParams } from 'react-router-dom';
const [search] = useSearchParams();
console.log(search.get('id'));

11. React 中 window.scrollTo函数不管用是怎么回事?如何解决React中滚动顶部不管用的问题?

问题分析

导致这种问题发生一般都是因为你滚动的功能应该绑定到某个元素上面,而不是直接用window

解决方案

使用ref,配合页面元素滚动 解决问题

CSS

.xiaojin-demo{
  height: calc(100vh - 100px);
  overflow-y: scroll;
}

TSX

import React, {  useRef  } from "react";
const ref = useRef(null);

const backToTop = ()=>{
  ref.current && ref.current.scrollTo({ top: 0, behavior: 'smooth' })
}
<div className="resource-approve" ref={ref}>
  <div>
    Lorem ipsum dolor sit amet, consectetur adipisicing elit. A aspernatur atque, debitis ex
    excepturi explicabo iste iure labore molestiae neque optio perspiciatis
  </div>
  <div>
    Aspernatur cupiditate, deleniti id incidunt mollitia omnis! A aspernatur assumenda
    consequuntur culpa cumque dignissimos enim eos, et fugit natus nemo nesciunt
  </div>
  <div>
    Alias aut deserunt expedita, inventore maiores minima officia porro rem. Accusamus ducimus
    magni modi mollitia nihil nisi provident
  </div>
  <div>
    Alias aut autem consequuntur doloremque esse facilis id molestiae neque officia placeat,
    quia quisquam repellendus reprehenderit.
  </div>
  <div>
    Adipisci blanditiis facere nam perspiciatis sit soluta ullam! Architecto aut blanditiis,
    consectetur corporis cum deserunt distinctio dolore eius est exercitationem
  </div>
  <div>Ab aliquid asperiores assumenda corporis cumque dolorum expedita</div>
</div>

12. cdn.jsdelivr.net下载失败的多种处理方案, formily @designable/react-settings-form下载https://cdn.jsdelivr.net/npm/monaco-editor@0.36.1/min/vs/loader.js报错失败异常处理解决方案

解决方案1 有的依赖不是写死的,比如这个

我们就可以采用下面方式解决

import {setNpmCDNRegistry} from '@designable/react-settings-form'
setNpmCDNRegistry('//fastly.jsdelivr.net/npm') // 也可以把资源下载到本地,使用本地的域名

比如下面这个monaco-editor/loader提供了这种方式解决

By using the .config method we can configure the monaco loader. By default all sources come from CDN, you can change that behavior and load them from wherever you want

import loader from '@monaco-editor/loader';

// you can change the source of the monaco files
loader.config({ paths: { vs: '...' } });

// you can configure the locales
loader.config({ 'vs/nls': { availableLanguages: { '*': 'de' } } });

// or
loader.config({
  paths: {
    vs: '...',
  },
  'vs/nls' : {
    availableLanguages: {
      '*': 'de',
    },
  },
});

loader.init().then(monaco => { /* ... */ });

解决方案 2 如果文件是写死的

搜索包文件后发现这个文件名是写死的

  • 下面解决步骤仅供写死的类型的参考
  • 注意事项:monaco-editor其实不是写死的cdn路径配置,我们可以观察文档,发现此包有提供修改CDN地址的函数,附属在上面的方案1最后面
  var config = {
    paths: {
      vs: 'https://cdn.jsdelivr.net/npm/monaco-editor@0.36.1/min/vs'
    }
  };

将@monaco-editor从node_modules复制到我们的项目目录下

  • 修改项目依赖为项目目录下,而不是node_modules
  • @monaco-editor/react 和 @monaco-editor/loader 改为 自己项目路径下

批量替换

也可以把资源下载到本地,使用本地的域名


大功告成

接下来请求里就没有之前的了,也可以把cdn替换为本地的资源哦~~

13.The package "@esbuild/win32-x64" could not be found, and is needed by esbuild.

failed to load config from xxx\vite.config.ts
error when starting dev server:
Error: The package "@esbuild/win32-x64" could not be found, and is needed by esbuild.
If you are installing esbuild with npm, make sure that you don't specify the
"--no-optional" or "--omit=optional" flags. The "optionalDependencies" feature
of "package.json" is used by esbuild to install the correct binary executable
for your current platform.

解决方案

手动安装完成之后,再次运行 npm run dev 即可

npm i @esbuild
npm run dev

14. vite突然不热更新了怎么办???10秒钟解决Vite hmr热更新失效BUG

解决方案

在vite.config.ts里添加一点代码,然后重启项目即可

server: {
    watch: {
      usePolling: true,   // 修复vite热更新失效
    },

15.待继续补充

解决方案

今天就写到这里啦~

  • 小伙伴们,( ̄ω ̄( ̄ω ̄〃 ( ̄ω ̄〃)ゝ我们明天再见啦~~
  • 大家要天天开心哦

欢迎大家指出文章需要改正之处~
学无止境,合作共赢

在这里插入图片描述

欢迎路过的小哥哥小姐姐们提出更好的意见哇~~