April 28 项目总结
modal 和上级组件 和 modal的下级组件 的值传递
结论:
可以为 modal 传入一个 reactNode (组件),展示这个组件的值(值是时实变化的),
这个 modal 调用上级组件的方法作为自己的 onOk 和 onCancel ,
在上级组件传入的函数里 执行一些表单操作,
自己 只是做了一个展示作用!
作为被传入 modal 组件的 reactNode ,使用 forwardRef 和 useImperativeHandle 暴露自己的方法和
值,让得 modal 的 上级组件、(也是自己的上级组件)调用这些方法。
从而完成表单操作,或者是将这些暴露出来的表单值,
用 useState 或 useRef 将值保存再传给其他需要展示这些数据的组件。
如此,完成了一次比较离奇、奇葩的组件展示、组件值的传递使用。
export interface SwitchInpType {
TITLE_LIST: Array<{
text: string;
key: string;
}>;
NUMS: string;
}
const SwitchInp: React.FC<SwitchInpType> = props => {
const submitForm = () => {
hotRef.current.getFormValue();
};
const handleCancel = () => {
setVisit(false);
};
const handleOk = () => {
const {list, num} = switchRef.current?.getParams();
query.current = {
list,
num,
};
const hotSearchConfigParams = list.map((item: any) => ({
appName: item.label,
name: item.inpVal,
enable: item.swiVal,
hotSearchConfigId: item.hotSearchConfigId,
queryCount: num,
}));
const queryCount = num;
const params = {
hotSearchConfigParams,
queryCount,
};
(async () => {
const res = await editHot(params);
if (res === ZERO) {
message.success('变更成功', 1);
return;
}
message.error('变更失败', 1);
})();
setVisit(false);
};
const modalConfig = () => {
if (modalType === CREATE || modalType === EDIT) {
return {
visit,
handleOk: submitForm,
handleCancel,
reactNode: <CreateHot {...createHotConfig} />,
NUMS,
title: TITLE_TWO,
};
} else {
return {
visit,
handleOk,
handleCancel,
reactNode: (
<div style={{textAlign: 'center'}}>
<div style={{display: 'inline-block', marginRight: '30px'}}>
<SwitchList {...props} ref={switchRef} />
</div>
</div>
),
NUMS,
title: TITLE_ONE,
};
}
};
return (
<>
...
..
<ModalView {...modalConfig()} />
</>
);
}
export interface Mutable {
getFormValue: () => void;
resetForm: () => void;
}
const CreateHot = (props: PropsCreateHot, ref: ForwardedRef<Mutable>) => {
const [form] = Form.useForm();
const resetForm = () => {
form.resetFields();
};
...
..
const getFormValue = async () => {
form.validateFields()
.then(values => {
if (values) {
if (type === EDIT) {
sendParams.hotSearchId = copyFields.hotSearchId || '';
(async () => {
const res = await editHotSearch(sendParams);
if (res === ZERO) {
resetForm();
message.success('更新成功', 1);
getSearchList();
handleCancel();
}
})();
}
}
})
.catch(errorInfo => {
console.error('errorInfo', errorInfo);
});
}
useImperativeHandle(ref, () => {
return {getFormValue, resetForm};
});
return (
<Form
form={form}
...
..
>
...
..
</Form>
)
}
export default forwardRef<Mutable, PropsCreateHot>(CreateHot);
interface Refs {
getParams: () => {
list: any[];
num: number;
};
}
const SwitchList = (props: SwitchInpType, ref: ForwardedRef<Refs>) => {
const {num, numberChange, list, listChange} = useHome(NUMS);
const getParams = () => {
const defaultVal = list.map((item: any) => {
if (!item.inpVal) {
item.inpVal = item.label;
return item;
}
return item;
});
return {
list: defaultVal,
num,
};
};
useImperativeHandle(ref, () => ({
getParams,
}));
return (
<div className={styles.switchList}>
{list.map((item, index) => {
const {label, inpVal, swiVal} = item;
return (
<div key={label} className={styles.listItem} style={{...TYPE_ONE}}>
<span className={styles.label}>{label}</span>
<Input
className={styles.inp}
value={inpVal}
onChange={e => listChange('inpVal', index, e.target.value)}
disabled={swiVal && NUMS !== QUERYNUMS}
/>
<Switch
checked={swiVal === ZERO}
onChange={e => listChange('swiVal', index, e)}
size='default'
checkedChildren='开'
unCheckedChildren='关'
defaultChecked
/>
</div>
);
})}
</div>
)
}
export default forwardRef<Refs, SwitchInpType>(SwitchList);
import React, {ReactNode} from 'react';
import {Modal} from 'antd';
import styles from './index.less';
const SEARCH_NUMS = '搜索数量设置:';
interface Type {
visit: boolean;
handleOk: () => void;
handleCancel: () => void;
reactNode?: ReactNode;
NUMS: string;
title: string;
}
export default (props: Type) => {
const {visit, handleOk, handleCancel, reactNode, NUMS, title} = props;
return (
<>
<Modal
width={700}
title={title}
visible={visit}
className={styles.modal}
onOk={() => {
handleOk();
}}
onCancel={handleCancel}
centered
style={{display: NUMS === SEARCH_NUMS ? 'flex' : ''}}
>
{reactNode ? reactNode : null}
</Modal>
</>
);
};
import {useState, useEffect} from 'react';
import {getHotConfig} from '@/constants/actions';
export default (NUMS: string) => {
const [num, setNum] = useState(1);
const [list, setList] = useState<any[]>([]);
console.warn('NUMS', NUMS);
const numberChange = (val: number) => {
setNum(val);
};
useEffect(() => {
(async () => {
const result = await getHotConfig();
setList(
result.map((item: any) => ({
label: item.appName,
inpVal: item.name,
swiVal: item.enable,
hotSearchConfigId: item.hotSearchConfigId,
num: item.queryCount,
}))
);
setNum(result[0].queryCount);
})();
}, []);
const listChange = (flag: string, index: number, value: any) => {
setList(
list.map((item, ind) => {
if (ind === index) {
if (flag === 'swiVal') {
item[flag] = value ? 0 : 1;
return item;
}
item[flag] = value;
return item;
}
return item;
})
);
};
return {
num,
numberChange,
list,
listChange,
};
};