子组件如下:
import { Button, Select } from "antd";
import { useState } from "react";
const BatchOperation = (props: BatchOperationProps) => {
const { options = [], onOk: globalOk, onChange } = props;
const [selectedOption, setSelectedOption] = useState<OperationType>(options[0]);
const { onOk = globalOk } = selectedOption;
return <div style={{ padding: 6, border: '1px solid #d8d8d8', display: 'inline-flex', gap: 6 }}>
<div>
<Select
options={options} defaultValue={selectedOption?.value}
dropdownMatchSelectWidth={false} showSearch={false}
style={{ width: 'max-content', maxWidth: 160 }}
onChange={selValue => {
const selected = options.find(({ value }) => value === selValue);
if (!!selected) {
setSelectedOption(selected);
onChange?.(selValue);
} else {
throw '选项错误';
}
}}></Select>
</div>
<Button type="primary" onClick={() => {
onOk?.();
}}>Button</Button>
</div>;
};
export default BatchOperation;
export interface OperationType {
value: string;
label: string;
onOk?: () => Promise<void>;
}
interface BatchOperationProps {
options: OperationType[]
onOk?: () => Promise<void>
onChange?: (value: string) => void
}
父组件如下:
import { ProColumns, ProTable } from '@ant-design/pro-components';
import { useState } from 'react';
import BatchOperation from './Batch';
import './index.css';
const Test = () => {
const [selectedRowKeys, setSelectedRowKeys] = useState<React.Key[]>([]);
const columns: ProColumns<any>[] = [
{
title: '员工姓名',
dataIndex: 'name'
},
{
title: '员工工号',
dataIndex: 'code'
}
];
const onOk = async () => {
console.info('ok: ', selectedRowKeys); // 3
};
return (
<ProTable
bordered rowKey="code" search={false} options={false} columns={columns} dataSource={dataSource}
rowSelection={{
selectedRowKeys,
onChange: (keys, rows) => {
console.info('selected keys ', keys);
setSelectedRowKeys(keys);
}
}}
toolbar={{
menu: {
items: [{
key: 'batch',
label: <BatchOperation
onChange={() => {
console.info('change...');
setSelectedRowKeys([]);
}}
// onOk={() => onOk()} // 2
options={[
{ value: 'A', label: '选项一' },
{ value: 'B', label: '选项二', onOk: () => onOk() } // 1
]}
/>
}]
}
}}
/>
)
};
export default Test;
const dataSource = [
{
name: '张三',
code: 'A1'
},
{
name: '李四',
code: 'A2'
}
];
如下图操作,进入页面直接选选项二,然后任意勾选之后点按钮,ok的输出不对。
但是像下面这样操作,ok的输出是正确的。
但是使用注释// 2 位置的函数,不实用// 1的,无论怎么操作都是正常的。
请问下这是什么原因啊?
组件内部的任何函数,包括事件处理函数和 Effect,都是从它被创建的那次渲染中被「看到」的,所以引用的值任然是旧的。
所以无论是
结果都是
你说的 注释// 2 位置的函数 是因为每次修改父组件的值都会刷新当前组件及其子组件
options 里的方法表现 ' 异常 ' 是因为useState对其进行了缓存