- npm安装@material-ui/core依赖时报错:
问题产生的可能原因以及对应的解决方法:
- 版本不支持:降低版本
- 权限不够:
方法一:删除C:\Users{账户}\下的npmrc文件
方法二:使用npm cashe clean --force命令清理缓存
方法三:使用npm install --save --legacy-peer-deps @material-ui/core命令
- 问题二:
- 请求的useMutation停止执行onSuccess和onError,并直接抛出错误。
问题产生的可能原因以及对应的解决方法:
在未处理完useMutation的请求时,弹窗就被直接关闭了:将关闭弹窗的方法放置在onSuccess和onError内执行。
总结:若组件被卸载时又被立即重新渲染则会报错。
探究:如何解决该问题?
应对策略: - 方法一:先在组件内设置一个ref变量状态,并在useEffect里重新设置ref变量状态(用于标记该组件是否已被渲染),再在函数内根据ref变量状态判断决定是否重新渲染组件。
- 方法二:直接将函数写在useEffect内部,同时定义一个布尔值用于标记组件是否已渲染,并在函数内根据布尔值判断决定是否重新渲染组件。
知识点延申: - react渲染的机制分为Stack Reconciler和Fiber Reconciler。
- fiber为react渲染过程中的任务单位。👉详解
- react组件的渲染分为render和commit,在render过程中发现需要更新的部分这一步骤为异步操作,而在commit过程中完成更新的部分这一步骤为同步操作。useEffect的宏观表现为在react组件第一次渲染和每次更新之后执行,实际上是在commit结束之后立刻执行的,故也会在组件的卸载操作完成之后执行。👉详解
👉关于react源码
-
鼠标事件:
监听鼠标移入:
其它鼠标事件:
-
阻止冒泡与默认事件:
或者使用useReducer:
-
问题三:调用钩子时经典的错误
问题产生的原因:
本质原因:👉详解
解决方法:
-
如何避免组件由于重新渲染前被销毁而导致的报错?
解决方法:使用闭包,增加一个flag变量用于判断组件是否重新渲染。 -
自定义组件样式属性:
自定义的样式属性一般会覆盖组件自带的样式属性(可在控制台观察到其位置),故在自定义组件样式时,可以在组件上一级取组件的类名对其样式进行修改。(一般使用’&.类名‘的方法修改组件自带的样式属性或者使用’& .类名‘的方法修改组件内部dom元素的样式属性) -
自定义组件基础:
/** @jsxImportSource @emotion/react */
import * as React from "react";
interface Props {
className?: string;
children?: React.ReactNode;
}
export default function CustomComponent({ className, children }: Props) {
return (
<div className={className} css={{}}>
{children}
</div>
);
}
-
搭建react项目时遇到的问题: Cannot find module ‘@emotion/react/jsx-runtime’ or its corresponding type declarations
解决方法:将新建的文件置于src下的pages文件下 -
方法/函数里面不可以调用hook:
若在渲染结构时同时处理副作用即将渲染结构的代码与处理副作用的代码写在同一个函数或者代码块中时,会产生渲染错误的bug。 -
在使用所有涉及到初始值的组件或者API时,应考虑对其作出一定的处理:
解决方法: 一般对于组件的子组件可传可不传参数的情况或者组件的子组件某个参数可能接受不同的值时,可以采取if判断然后进行传值的方法。
-
无限加载:上下的翻页滚动,需要限制滚动容器的高度
写法一:
写法二:
处理下拉的分页加载:
防抖处理: -
vue→react的反模式:
反模式的原因:依赖项始终不变,故useEffect只会调用一遍。若stateA被修改为不同的值即依赖项不同时,useEffect会随着依赖项的改变被调用,但是这样又会引起react的重复渲染。(setStateA(‘stateA+1’)会引起一次渲染,useEffect被调用时,setSateBDependsOnStateA(stateA+‘samurai’)也会引起一次渲染。)
正确的写法:
-
关于使用useQuery时常见的反模式:
模式一:后台返回的数据A可以直接使用即可以直接用于页面渲染时,则不应该在组件中创建状态B存储后台返回的数据A,并用B进行渲染。(该种模式下,对于后台请求回来的数据,应该直接使用,切勿创建冗余状态。)
模式二:后台返回的数据A无法直接使用即不能直接用于页面渲染时(例如:上下滚动分页的处理),则应该在组件中创建状态B存储后台返回的数据A,并用B进行渲染。(该种模式下,对于后台请求回来的数据,不能直接使用,应创建备份数据。) -
关于有分页的表格一些常见问题:
针对在有分页的表格的不同分页页面进行的勾选操作:
方案一:可以在头部搜索模块,通过回显已勾选项的方法来记录用户的操作。
方案二:只允许用户操作当前页面数据,当用户更改搜索条件、切换分页或者在不同页面进行勾选的时候置空已选项。
场景一:对于有分页的表格,只允许用户操作当前页面数据时,用户在已勾选若干项后切换分页、更改搜索条件或者在不同页面进行勾选时,应将已勾选项都清空。
场景二:对于有分页的表格,如果用户在某一个只有一条数据的页面点击操作按钮(删除)或者存在多个用户同时点击删除时,删除成功后应该让用户回到上一页。
-
搭配使用Ant Design的组件时:
问题一:Select组件:value必须为确定的值或者为null或者为undefined时,其placeholder才会显示。(value为‘ ’时,其placeholder不会显示。)
问题二:请求回来的下拉数据为模糊查询的结果时,如何保证在编辑状态下回显出正确的数据? 解决方法:在新增状态下时,保存状态时将用户选中的name和code放在一起保存。
问题三:对于某些组件,其子元素需要符合要求:
图一:
图二:
问题四:对于无法直接修改样式(即其dom结构层级动态变化)的组件,可以使用ClassNames组件和css()方法将css样式传入其类名。(一般框架组件若有行内样式,则表明其样式为非受控的,是无法直接修改的。)
问题五:由于ant design组件源码内部为less语法,无法直接将less变量转化为JavaScript变量,故无法实现直接使用ant design组件自带的样式,需要将使用到的组件的样式再全部重复一遍进行覆盖,但这种方式效率极低。
解决方法:👉详情
根据目前项目里已有的需求对ant-design组件进行重新修改的版本:👉详情
问题六:如何使用拖拽组件(Dragger)时自定义上传逻辑?
解决方法:使用customRequest属性自定义上传逻辑,使用组件的onChange去主动修改上传文件状态。 -
文件下载处理:
- 根据请求参数下载指定内容的文件:
- 下载指定文件格式的空白文件
download:如果有值的话,其值则为下载文件的名称。👉详情
- 关于文件上传:
import { useMutation } from "react-query";
import { useFetch } from "shared/hooks";
import { JSONResponse } from "types";
export default function useUpload() {
const fetch = useFetch();
return useMutation(async (file: File) => {
const formData = new FormData();
formData.append("file", file);
const response = await fetch(" ", {
method: "POST",
headers: {
"Content-type": "application/json",
},
body: formData,
});
const parsed: JSONResponse<{ filePath: string }> = await response.json();
if (parsed.code === 0) {
return parsed.data;
} else {
throw parsed;
}
});
}
- 内置tab页面与页面路由结合:本质上为一个设计bug。
存在的已知问题:同时打开两个tab页面A和B,在其中一个页面A上进行一些操作后,切换至另一个页面B并刷新B页面时,会导致A页面直接被关掉。
解决方法:避免将页面路由作为tab的activeKey使用。 - sso相关的问题:
- 项目V1.0:
auth-provider.ts:定义sso的真实接口调用方法。
use-sso-login.ts:从auth-provider里引用sso的真实接口调用方法作为mutationFn。
sso-impl.tsx:从use-sso-login引用mutationFn。
sso-no-token.tsx:登录失败后的跳转逻辑。
sso.tsx:引入sso-impl、sso-no-token,根据路由参数渲染sso-impl或者sso-no-token。
参考dms-pc项目 - 项目V2.0:
api.ts:定义sso的真实接口。
auth-client.ts:从api里引入sso的真实接口,定义sso的调用方法。
reducer.ts:定义sso状态下处理用户登录信息的方法。
authentication-context.ts:定义sso调用方法类型,创建具有该类型的context。
authentication-provider.tsx:定义的sso调用方法,并在方法内创建auth-client实例,引用其实例的sso的调用方法;创建reducer实例,引用其实例的sso状态下处理用户登录信息的方法;引用authentication-context,创建AuthenticationContext.Provider并将sso调用方法作为其value。
use-authentication.ts:获取authentication-context的value即sso调用方法。
use-sso-login.ts:由use-authentication获取sso调用方法,并将其作为mutationFn。
sso-impl.tsx:从use-sso-login引用mutationFn。
sso-no-token.tsx:登录失败后的跳转逻辑。
sso.tsx:引入sso-impl、sso-no-token,根据路由参数渲染sso-impl或者sso-no-token。
参考aid-pc项目
-
sourcemap文件泄露漏洞问题:👉详情
GENERATE_SOURCEMAP = false; -
fetch在react中的 race condition问题:
解决方法:👉参考(项目V3.0:do-fetch) -
啊这:
-
啊这:
-
啊这:
-
啊这: