# 📆 2021.01.02
# 问题一
问题描述:使用
EditableProTable组件,一直点击不了解决:
// 官网,使用了key,作为唯一值,
<EditableProTable rowKey="id" ... />
// 自己项目,使用了key,作为唯一值,所以rowKey要改成使用可以
<EditableProTable rowKey="key" ... />
1
2
3
4
2
3
4
# 问题二
- 问题描述:使用
mock请求数据,但是请求不了,根据就执行不了postMoldingData函数
...
export default {
'POST /api/v1/molding?sn=dev1&example=query_workshopd': postMoldingData,
};
1
2
3
4
5
2
3
4
5
- 解决:将请求的接口改成如下,这是不是说明,设置自定义接口不能携带
&和?呢?
...
export default {
'POST /api/v1/molding': postMoldingData,
};
1
2
3
4
5
2
3
4
5
# 📆 2021.01.03
问题描述:在
antd pro v5项目中,使用openAPI的方式只要接入swagger。现有post接口,需要发送requestBody,但一直显示requestBody发送了空数据解决:给
requestBody中的内容设置格式限制
// 之前,得到requestBody为空
"requestBody": {
"description": "List of user object",
"content": {
"*/*": {...
// 现在,能准确得到requestBody的值
"requestBody": {
"description": "Please input request body value ",
"content": {
"application/json": {...
1
2
3
4
5
6
7
8
9
10
2
3
4
5
6
7
8
9
10
# 📆 2021.01.06
# 问题一
- 问题描述:使用
form表单验证validator callback警告 - 解决:
return new Promise((resolve, reject) => {
reject("不能重复");
});
//或
return Promise.reject("不能重复");
1
2
3
4
5
2
3
4
5
# 问题二
- 问题描述:使用
EditableProTable组件,用来实现可编辑行,现需要对于可编辑行的表单项进行验证,一般来说使用使用form表单的rules的validator进行验证,很明显只抛出了错误,没有给出提示。 - 解决:手动添加提示,主要代码实现如下
const [checkIdMsg, setCheckIdMsg] = useState('');
const checkId = (_, value, callback) => {
if (value) {
let isRptId = dataSource.some((item) => item.id === value);
if (isRptId) {
setCheckIdMsg('id不能重复');
return Promise.reject();
} else {
setCheckIdMsg('校验成功');
return Promise.resolve();
}
} else {
setCheckIdMsg('此项为必填项');
return Promise.reject('此项为必填项');
}
};
...其它代码
{
title: 'id',
key: 'id',
// key: `${dataSource.map((item)=>item.sn)}`,
dataIndex: 'id',
width: '30%',
formItemProps: (form, { rowIndex }) => {
return {
rules: [
{
validator: checkId,
message: checkIdMsg ? checkIdMsg : '此项为必填项',//validator后能跟message,还能这样子写?!
},
],
};
},
editable: (text, record, index) => {
if (text) {
return false;
}
},
},
...其它代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
# 📆 20220112
# 问题一
- 问题描述:React 中使用
dva进行开发,出现以下报错信息。
Either wrap the root component in a <Provider>, or pass a custom React context provider to <Provider> and the corresponding React context consumer to Connect(ConfigInjMachine) in connect options.
1
- 解决:文件名写错,
model.js写成modles.js,注意不要将文件名写错!
# 📆 20220115
- 问题描述:React+antd pro 的开发中,有孙子组件
<GrandsonCmpt>,儿子组件<SunCmpt>,父亲组件<FatherCmpt>。在孙子组件中使用 dispatch 传最新数据dataSource,在父亲组件中拿到这个数据并渲染出来,但在父亲组件中渲染不出来。 - 原因:在父亲组件中使用
setTimeout打印数据,是能够打印出来,说明是和事件的循环机制有关。 - 具体实现
实现一:
//父亲组件
const { dataSource, columnsSource } = this.props;
setTimeout(() => {
//能打印这个数据
console.log("setTimeout", dataSource);
});
// 孙子组件的实现
handleOk = async () => {
const {handleModal}=this.props
this.props.dispatch({ type: `${namespace}/setModalVisible`, payload: false });
try {
const { FormItemValue } = this.props;
switch (Object.keys(FormItemValue)[0]) {
case 'add':
try {
const formValues =await this.form.current.validateFields()
this.props.dispatch({ type: `${namespace}/setModalVisible`, payload: false });
}
// 调用父组件中的方法
this.props.getModalData()
catch (error) {}
break;
default:
break;
}
};
// 父亲组件
getModalData=()=>{
// 这个方法是给孙子组件调用,用于获取model的表单里最新数据,因为settimeout才能获取最新数据, 说明是异步调用问题
// 获得model的表单的数据属于异步任务,而dataSource渲染是主任务,要让dataSource再更新,放在异步之后再调用更新
// 使用[...]更新地址地址,表格才会从新渲染
this.setState({
dataSource1:[...this.props.dataSource]
})
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
问题:数据得到了更新,实现的整个过程就是孙子组件调用父组件中的方法,具体操作就是 将这个方法传给儿子组件,儿子组件再传给孙子组件,孙子组件调用这个方法,很繁琐的过程 ,并且耦合度过高,不易于后期的维护。
实现二:
// 父亲组件
<Table
rowSelection={rowSelection}
columns={columnsSource}
// {dataSource}改成{[...dataSource]}
dataSource={[...dataSource]}
/>
1
2
3
4
5
6
7
2
3
4
5
6
7
原因:数组类型的数据(数组是引用类型的数据),单纯的赋值,只是改变了数据的指向,其数据的地址没有变化。在此项目中直接将返回结果直接赋值那么 react 会认为你这个数组没有更新(react 数据的更新是根据数据地址的变化进行更新的),可以尝试下将数据用 es6 的扩展运算符展开,比如 list = [...获取到的数据],然后再 setState,当然也有可能是 rowKey 没有更新的原因,如果你的数据量不是很大,可以尝试给 rowKey 加上一个时间戳。
参考:antd+react 数据更新后,Table 组件不刷新 (opens new window)
// 父亲组件
<Table
rowKey={(record) => {
return record.id + Date.now(); //在这里加上一个时间戳就可以了
}}
rowSelection={rowSelection}
columns={columnsSource}
dataSource={{dataSource}
/>
1
2
3
4
5
6
7
8
9
2
3
4
5
6
7
8
9
# 问题二
- 问题描述:使用 antd 开发,使用
<Modal>和<Form>弹出表单框,将数据进行修改。点击确定修改按钮之后,显示的是上一次修改的数据。 - 原因:修改的数据没有及时更新,说明数据是修改了,但是没有得到及时的更新渲染
- 解决:让每次的
<Form>表单的key不一样
<Form key={(Math.random() * 1000000).toFixed(0)} ...do something/>
1
# 问题三
- 问题描述:生成 antd 列表组件的时候需要要有唯一的 key
- 解决:
// 比如,以下操作实现了产生随机不重复的key
<Form key={new Date() + (Math.random() * 1000000).toFixed(0)} />
1
2
2
# 📆 20210117
- 问题描述:使用 React,antdpro,dva 进行开发。现有儿子组件,封装了上传文件功能,将上传文件后的内容数据
fileContent使用dva进行管理;在父组件中拿到fileContent,然后更新dataSource,但在更新后,在父组件添加数据后,一直得不到新数据,只有拿到fileContent的数据。 - 解决:
目录结构:
├── JsonTable1
├── components
├──UploadFile
├──index.jsx
├──index.jsx
├──modle.js
├──utils.js
1
2
3
4
5
6
7
8
2
3
4
5
6
7
8
//部分代码
function FatherCmpt(props) {
const { fileContentRes } = props;
const [dataSource, setDataSource] = useState(fileContentRes);
console.log("外面的dataSource", dataSource);
const [DataSourceTemp, setDataSourceTemp] = useState(false);
// 改后这样写1
useEffect(() => {
setDataSource(fileContentRes);
fileContentRes.length !== 0 && setDataSourceTemp(!DataSourceTemp);
}, [fileContentRes]);
// 改后这样写2
useEffect(() => {
generateColumns();
}, [DataSourceTemp]);
const generateColumns = () => {
let arrKeys = ["sn", "name", "ip"];
let tmp = arrKeys.filter((item) => item !== "key");
let columnsValue = tmp.map((item) => {
return {
title: item,
key: item,
dataIndex: item,
width: "30%",
valueType: showIptNum(item),
};
});
columnsValue.push({
title: "Action",
valueType: "option",
width: 200,
render: (text, record, _, action) => {
console.log("里面的dataSource", dataSource);
return (
<Space>
<a
key="editable"
onClick={() => {
setDelData(record);
action?.startEditable?.(record.key);
}}
>
编辑
</a>
<Popconfirm
title="确定删除?"
onConfirm={() => handleDelete(record, dataSource)}
>
<a>删除</a>
</Popconfirm>
</Space>
);
},
});
setColumns(columnsValue);
};
// 改后这样写3
const handleChange = (newlist) => {
setDataSource(newlist);
setDataSourceTemp(!DataSourceTemp);
};
return (
<>
<div style={headerSty}>
<div style={{ marginLeft: "10px" }}>
<UploadFile></UploadFile>
</div>
</div>
<EditableProTable
rowKey="key"
headerTitle="数据列表"
request={async () => ({
data: [...dataSource],
})}
recordCreatorProps={
position !== "hidden"
? {
position: position,
record: () => ({ key: (Math.random() * 1000000).toFixed(0) }),
}
: false
}
value={[...dataSource]}
defaultData={[...dataSource]}
onChange={handleChange} // 改后这样写4,关键这里要再更新数据
columns={columns}
bordered
editable={{
type: "multiple",
editableKeys,
onSave: async (rowKey, data, row) => {
await waitTime(1000);
setDataSource([...dataSource]);
},
onChange: setEditableRowKeys,
onCancel: () => {
// setIsedit(false);
},
onDelete: () => {
handleDelete(delData);
},
}}
></EditableProTable>
</>
);
}
const mapStateToProps = ({ fileContent }) => {
return {
...fileContent,
};
};
export default connect(mapStateToProps)(FatherCmpt);
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
# 📆 20210124
# 问题一
- 问题描述:react 开发,在
componentDidMount中得到get请求的数据res,想在之后的事件中得到刚开始get请求的数据,但发现数据随着页面的数据变化了,得不到原始数据 - 原因:引用类型的赋值问题,使用深拷贝,这样创建的对象就会指向新的地址,当进行修改的时候,另一个属性值不变。
- 解决:
state = {
initData: {},
cancelData: {},
};
componentDidMount = () => {
queryInitData().then((res) => {
this.setState({
initData: res,
// cancelData: res,//这种写法得不到开始的数据res
cancelData: JSON.parse(JSON.stringify(res)), //深拷贝,想得到的是最初进入这个页面的值
});
});
};
...有this.setState({initData: 其它数据});
handleCancel = () => {
this.setState({
initData: JSON.parse(JSON.stringify(this.state.cancelData)), //不然,这里的数据跟着变化
});
};
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
# 问题二
问题描述:react 开发,数据已经更新,但视图没有更新,打印的时候发现,这个数据渲染了两次,第一次是上一次的数据,第二次是新的数据。
解决:每次都生成不同且唯一的
key值。
- key 相同,若组件属性有所变化,则 react 只更新组件对应的属性;没有变化则不更新。
- key 值不同,则 react 先销毁该组件( 有状态组件的 componentWillUnmount 会执行 ),然后重新创建该组件( 有状态组件的 constructor 和 componentWillUnmount 都会执行 )。
// 每次都生成唯一的key值
<组件 key={+new Date() + Math.random()}><组件/>
1
2
3
2
3