基于React-hooks对antd显示弹窗组件的二次封装

弹窗在项目业务中很常见,接下来我们将基于 antd 的 Modal 组件实现 2 次封装。这个例子我们将实现一个选择城市的 SelectCityDialog 组件。

基本思路就是:

(1)弹窗组件的显示和隐藏由 SelectCityDialog 内部一个变量 visable 来控制,而这个值为 true 或者 false 则是由我们传入的值来控制。也就是说父组件传值给 SelectCityDialog 控制显示和隐藏

(2)由于我们要在外部(父组件)来打开这个弹窗,所以我们要在外部定义一个变量比如我们就叫 vis,它每次值的变化则会传递给 SelectCityDialog

(3)在 SelectCityDialog 内部,我们要点击取消或确定会关闭弹窗,而我们说过弹窗组件的显示和隐藏由 SelectCityDialog 内部一个变量 visable 来控制,而这个值为 true 或者 false 则是由我们传入的值来控制,而不是 SelectCityDialog 本身的 visable 来更改,所以关闭的时候我们需要让外部 vis 的值更改,进而引发 SelectCityDialog 传递过来的值发生更改。那怎么办呢?只能给组件传递一个函数,在关闭的时候让调用父组件的函数更改父组件内的 vis 的值更改,这样就能达到目的。

有点绕。但是只要我们理清楚这样一个关系就可以了。

(1)SelectCityDialog 内部的 visible===>控制 SelectCityDialog 显示、隐藏

(2)父组件的 vis=====>传值给 SelectCityDialog=====>引发 visible 变更

(3)SelectCityDialog 关闭=======>调用父组件的函数====>设置父组件的 vis 为 false,再次引发子组件的 visible 变更

接下来我们实现代码:

父组件,通过点击按钮打开弹窗
import SelectCityDialog from "../../components/SelectCityDialog/index"
import style from "./index.module.less"
function HouseStyle(props){
    const [visiable,setVisiable]=useState(false)
    const operDialogFunc=(flag)=>{
        setVisiable(flag)
    }
 return(
    <div>
        <Button 
            size="large" 
            onClick={()=>operDialogFunc(true)} 
            icon={<IconFont type="icon-dingwei" 
            style={{fontSize:"18px",color:"#ff8c00"}} />}>
            打开弹窗
        </Button>
        <SelectCityDialog 
            title="设置常用城市" 
            vis={visiable} 
            operDialogFunc={operDialogFunc}
            >
         </SelectCityDialog>
    </div>
)
}
export default HouseStyle

接下来是 selectCityDialog 组件:

export default function SelectCityDialog(props){
    let {title,operDialogFunc,vis}=props;
    const [cityVisable,setCityVisable]=useState(false)
    useEffect(()=>{
        console.log("vis:",vis)
        setCityVisable(vis)
    },[vis])
    return(
        <Modal
            title={title}
            centered
            visible={cityVisable}
            onOk={() =>operDialogFunc(false)}
            onCancel={() => operDialogFunc(false)}
            width={1000}
      >
        <div className={style['cur-locate']}>
            <div className={style['list-lf']}>当前定位</div>
            <div className={style['list-rf']}></div>
        </div>
        <div className={style['recently-select']}>
            <div className={style['list-lf']}>最近选择</div>
            <div className={style['list-rf']}></div>
        </div>
        <div></div>
      </Modal>
    )
}

注意我们在 useEffect 里对传过来的变量 vis 进行了监听。这样每次 vis 改变,我们都重新对 cityVisable 进行重新赋值。

到此基本上实现了弹窗效果。

优化:

如果直接把该组件引入。这样父组件渲染完成的时候子组件已经先完成挂载。这样会导致一个问题:如果子组件中的数据有问题。这样父组件会直接报错挂掉。我们需要一种机制;在父组件渲染完成以后,子组件是完全不存在的。也就是子组件内的任何报错不会影响到父组件。所以我们需要让子组件最开始是完全销毁的。只有在点击打开的时候才让它真正渲染;实现方式也很简单:

<SelectCityDialog 
    title="设置常用城市" 
    vis={visiable}
    operDialogFunc={operDialogFunc} > 
</SelectCityDialog>:null

效果图如下:

基于 React-hooks 对 antd 显示弹窗组件的二次封装

「点点赞赏,手留余香」

2

给作者打赏,鼓励TA抓紧创作!

微信微信 支付宝支付宝

还没有人赞赏,快来当第一个赞赏的人吧!

声明:本站所有文章,如无特殊说明或标注,均为本站原创发布。任何个人或组织,在未征得本站同意时,禁止复制、盗用、采集、发布本站内容到任何网站、书籍等各类媒体平台。如若本站内容侵犯了原著者的合法权益,可联系我们进行处理。
码云笔记 » 基于React-hooks对antd显示弹窗组件的二次封装

发表回复