我找到了办法。
我有一个父组件,类似于包装器或装饰器,但低于我的最终组件。
interface ModalProps {
title: string,
show: boolean,
setShow: Function,
value: number | string,
onSave: Function
}
const ModalInput: React.FC<ModalProps> = (props) => {
var { show, setShow, title, value, onSave } = props;
return (
<IonPopover isOpen={show} onDidDismiss={() => { setShow(false); }}>
<IonContent class="ion-text-center modal-content">
<IonCard>
<IonCardHeader>
<IonCardTitle>{title}</IonCardTitle>
</IonCardHeader>
<IonCardContent className="text-center">
{props.children}
</IonCardContent>
</IonCard>
<IonFooter>
<IonButton color="light" onClick={() => { setShow(false); }}>Cancel</IonButton>
<IonButton color="primary" onClick={() => { onSave(value); setShow(false); }}><IonIcon slot="start" icon={save} /> Save</IonButton>
</IonFooter>
</IonContent>
</IonPopover>
);
};
export default ModalInput;
需要道具来打开/关闭模式,一个标题,一个道具来获取子值和onSave,这是来自应用程序的回调。
然后我写了一个更高的组件来实现孩子。
所有的道具都进入 ModalInput 包装器。
interface InputProps {
onSave: Function,
show: boolean,
setShow: Function,
defaultValue: number
}
const WeightInput: React.FC<InputProps> = ({show, setShow, defaultValue, onSave}) => {
const [value, setValue] = useState<number>(defaultValue);
return (
<ModalInput show={show} setShow={setShow} title="Starting weight" value={value} onSave={onSave}>
<IonItem>
<IonInput value={value} onIonChange={e => setValue(parseFloat(e.detail.value!))}></IonInput>
</IonItem>
</ModalInput>
);
}
export default WeightInput;
最后如何使用它:
<WeightInput show={showWeight} setShow={setShowWeight} defaultValue={weight} onSave={(w:number) => setWeight(w)}/>
所以它是这样工作的:
- 在输入改变时,输入调用 setValue 来改变状态
- 状态改变也会改变模态组件的道具
- 点击确定后,模态组件将触发直接来自应用的 onSave 道具
所以应用应该只关心模式的值和状态。
模态组件应该只关心他的值和打开状态和ok回调
较高的组件包含输入逻辑并将 pther props 传递给模态组件。
也许这不是最好的方法,但在我有限的知识范围内,这是我能开发的最好的方法