项目所遇问题
1、通过useLocation()获取路由参数时,由于官方是没有定义query参数的,默认只定义了以下参数
{state, search, pathname, hash}
但是通过打印useLocation(),可以看到实际是有一个query参数的
import { useLocation } from 'react-router-dom';
const locationName = useLocation();
useEffect(() => {
console.log(JSON.stringfy(location)) // {"pathname":"/list","search":"?id=1","hash":"","query":{"id":"1"}}
}, [location])
当我们想通过该query拿取路由参数时候ts会提示 没有该参数
之后我去了umi的issue上找到了这个问题,官方修复过一版(umi3.x),但是基于class组件的(未测试)。函数组件的目前无法取到query。最终使用了一个替代方案:locatioName['query']
相关问题链接:Location 和 useLocation的query 缺少 ts 声明类型 #5278
2、父组件调用子组件方法的打开方式及其类型定义问题
父组件调用子组件的方法: useRef useImperativeHandle 官方链接
在使用的过程中涉及到类型定义,在最初的使用当中,一直以为是调用某个官方定义好的类型来使用,但是没有具体如何使用以及引入什么包,之后download下来了antdp查看了protable源码中该组件使用,学习了如何定义该类型。
type Test = {
load?: () => void | undefined // 在父组件中调用的子组件的方法
import React, {useState, useRef} from 'react';
const testRef = useRef<Test>()
const clickBtn = () => {
testRef.current?.load?.()
<RefTest tRef={testRef}></RefTest> // 子组件
import React, {useState, useEffect, useImperativeHandle} from 'react';
interface childProps {
tRef: React.MutableRefObject<Test | undefined> | ((tRef: Test) => void) | undefined
const RefTest: React.FC<childProps> = ({tRef}) => {
useImperativeHandle(tRef, () => ({
load: () => {
console.log(11111)
return (
</div>
export default RefTest;
3、使用!Boolean && ReactDom
可能会造成渲染逻辑错误 替换方案:三目运算符 (测试时无法复现了)
当遇到该问题时候解决:
Boolean ? <></> : ReactNode
4、useState()修改数据时,执行逻辑属于微任务。修改数据时,如果修改的值和当前值相同,不会触发useEffect的监听。也不会重新触发render。
const clickBtn = () => {
setTimeout(() => {
console.log('异步调用')
console.log(inputValue.toFixed(2))
setInputValue(inputValue + 1)
console.log('我在代码最后')
useEffect(() => {
console.log(`inputValue变成了${inputValue}`)
}, [inputValue])
// 执行顺序 我在代码最后 -> inputValue变成了xx -> 异步调用
5、TS下字符串和变量的拼接无法使用‘+’ 解决方式: 模板字符串
6、不要使用表单的绑定值当作rowKey: 表格中嵌套表单元素时,如果表格中的rowKey的取值设置为受控表单组件的绑定值时,当我们监听onChange修改值时,当前输入框会失去焦点。vdom重新patch,再次渲染了页面,导致失焦。
7、css显示问题:使用情景:修改块级元素下嵌套的antd 组件的样式
当设置了className,但是没有在其中定义样式,那么该类名是不会被编译的。当我们设置了类名之后,想要在global中修改该类名下的样式时,使用设置的类名是选择不到该节点的,需要使用由react编译好的类名来修改。当我们要修改包裹在某个块级元素中的引入组件的样式时。CSS modules
.hiddenInput {
width: 400px; // 任意定义一个样式,这样vdom才会编译该类名
:global {
.hiddenInput___1XowN { // 编译实际生成的类名
width: 400px;
.ant-form-item-control-input {
display: none;
8、formItem中的表单元素取值问题。
当formItem中添加了除了表单元素其他的元素时,这个时候通过getFieldsValue是无法取到formItem中的值的。
<Form.Item
label="方案名称"
name="activityName"
rules={[{ required: true, message: '请输入方案名称' }]}
<Input style={{ width: 800 }} maxLength={50} />元 // 此时是拿不到input的值的
</Form.Item>
如果需要在表单前后添加文字,则不能放在同一个formItem里面,
解决方案:可以使用Space或者再加一个formItem来存放文字
9、protable中设置查询条件输入规则
在官方文档中说的是使用
formItemProps:传递给 Form.Item 的配置,可以配置 rules,但是默认的查询表单 rules 是不生效的。需要配置 ignoreRules
ignoreRules属性要设置在proTable组件上
<ProTable
form={{
ignorerules: 0, // 提示不能用ignoreRules,只能小写,并且不能直接给boolean值, 所以给的0
10、自定义组件。实现表单控制
将自定义组件的值设置成受控的,可以通过InitValue/form.setField()方式赋值
// 定义参数
interface Ipros {
onChange?: (data: any) => void; // 可以不传,但是必须定义
value?: any[] // // 同上,用于控制绑定值
const { onChange = () => {}, value = []} = props;
二次封装的组件,将value绑定其中
<Cascader
options={dataInfo}
placeholder={placeHolder}
fieldNames={{ label: "areaName", value: "code" }}
onChange={getResult}
value={value}
在值改变时候操作,即触发上面的onChange时
const getResult = (value: any) => {
onChange?.(value); // 此时就成为form受控表单元素
11、protable设置search时 labelWidth 为数字
<ProTable
search={{
defaultCollapsed: false,
labelWidth: 100,
复制代码