欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

React實現(xiàn)動態(tài)調(diào)用的彈框組件

 更新時間:2022年08月25日 15:21:43   作者:qq_35757537  
這篇文章主要為大家詳細(xì)介紹了React實現(xiàn)動態(tài)調(diào)用的彈框組件,文中示例代碼介紹的非常詳細(xì),具有一定的參考價值,感興趣的小伙伴們可以參考一下

最近在用react開發(fā)項目,遇到一個需求——開發(fā)一個彈框組件。在react中創(chuàng)建一個組件是很簡單的,只需要使用class創(chuàng)建并引入就可以了,但是要做到可以用js調(diào)用這個組件而不是寫在jsx結(jié)構(gòu)里,那就需要用到ReactDOM.render這個方法了。

首先先來屢一下需求:

1、彈框里的可配置字段:標(biāo)題文字,提示文字,確認(rèn)和取消按鈕的顯示隱藏以及文字。
2、點擊確認(rèn)和取消按鈕后,可以觸發(fā)相應(yīng)的事件。
3、是否為短提示,短提示的時候,確認(rèn)和取消按鈕隱藏,并且2s后消失。

接下來用兩種方法創(chuàng)建一個彈框組件,并比較一下這兩種的差異。

下面先來實現(xiàn)一個普通的寫在jsx結(jié)構(gòu)里的組件:

彈框組件:DialogAlert.js

import React, { Component } from 'react';
import './index.scss';
?
class DialogAlert extends Component {
? ? constructor(props){
? ? ? ? super(props);
? ? ? ? this.state = {
? ? ? ? ? ? alertStatus:false,
? ? ? ? ? ? alertTitle:'提示', //標(biāo)題
? ? ? ? ? ? alertTip:'網(wǎng)絡(luò)錯誤', //提示
? ? ? ? ? ? cancelText:'取消',
? ? ? ? ? ? confirmText:'確認(rèn)',
?
? ? ? ? ? ? isShortTip:false, //是否為短提示,短提示的情況下不顯示'取消''確認(rèn)'(且2s后消失),且優(yōu)先級最高,其他配置無效
?
? ? ? ? ? ? isShowCancel:true, //是否顯示確認(rèn)按鈕
? ? ? ? ? ? isShowConfirm:true, //是否顯示確認(rèn)按鈕
?
? ? ? ? ? ? cancelCallbackFn:function(){}, //取消 回調(diào)函數(shù)
? ? ? ? ? ? confirmCallbackFn:function (){}//確認(rèn) 回調(diào)函數(shù)
? ? ? ? }
? ? }
?
? ? componentWillReceiveProps(nextProps) {
? ? ? ? let options = nextProps.dialogOpt || {};
?
? ? ? ? //如果是短提示
? ? ? ? if(options.isShortTip){
? ? ? ? ? ? options.isShowCancel = false;
? ? ? ? ? ? options.isShowConfirm = false;
? ? ? ? ? ? setTimeout(()=>{
? ? ? ? ? ? ? ? this.close()
? ? ? ? ? ? },2000)
? ? ? ? }
?
? ? ? ? this.setState({
? ? ? ? ? ? ...options
? ? ? ? })
? ? }
?
? ? //取消
? ? cancel = () => {
? ? ? ? this.state.cancelCallbackFn();
? ? ? ? this.close()
? ? }
? ? //確認(rèn)
? ? confirm = () => {
? ? ? ? this.state.confirmCallbackFn();
? ? ? ? this.close()
? ? }
? ? close = () => {
? ? ? ? this.setState({
? ? ? ? ? ? alertStatus:false
? ? ? ? })
? ? }
?
? ? render(){
? ? ? ? let opts = this.state;
? ? ? ? return (
? ? ? ? ? ? <div className="dialog-wrap" style={opts.alertStatus ? {display:'block'}:{display:'none'}}>
? ? ? ? ? ? ? ? <div className="dialog-box">
? ? ? ? ? ? ? ? ? ? <h6>{opts.alertTitle}</h6>
? ? ? ? ? ? ? ? ? ? <p>{opts.alertTip}</p>
? ? ? ? ? ? ? ? ? ? {!opts.isShowCancel && !opts.isShowConfirm ? null : (
? ? ? ? ? ? ? ? ? ? ? ? <div>
? ? ? ? ? ? ? ? ? ? ? ? ? ? {opts.isShowCancel ? (<span onClick={ () => this.cancel() }>{opts.cancelText}</span>) : null}
? ? ? ? ? ? ? ? ? ? ? ? ? ? {opts.isShowConfirm ? (<span className="confirm" onClick={ () => this.confirm() }>{opts.confirmText}</span>) : null}
? ? ? ? ? ? ? ? ? ? ? ? </div>
? ? ? ? ? ? ? ? ? ? ? ? )}
? ? ? ? ? ? ? ? </div>
? ? ? ? ? ? </div>
? ? ? ? )
? ? }
}
?
export default DialogAlert;

這里的數(shù)據(jù)更新用到了componentWillReceiveProps這個生命周期,當(dāng)props發(fā)生變化時執(zhí)行,初始化render時不執(zhí)行,在這個回調(diào)函數(shù)里面,你可以根據(jù)屬性的變化,通過調(diào)用this.setState()來更新你的組件狀態(tài),舊的屬性還是可以通過this.props來獲取,這里調(diào)用更新狀態(tài)是安全的,并不會觸發(fā)額外的render調(diào)用。

調(diào)用頁面index.js

在state中定義可配置字段的變量

import DialogAlert from '../../widget/DialogAlert/index';
?
//省略了組件的js
?
this.state = {
? ? dialogOpt:{
? ? ? ? alertStatus:false,
? ? ? ? alertTip:'我是自定義的內(nèi)容',
? ? ? ? cancelText:'取消2',
? ? ? ? confirmText:'確認(rèn)2',
? ? ? ? isShortTip:false,
? ? ? ? isShowCancel:true, //是否顯示確認(rèn)按鈕
? ? ? ? isShowConfirm:true, //是否顯示確認(rèn)按鈕
? ? ? ? cancelCallbackFn:function(){
? ? ? ? ? alert(0);
? ? ? ? }, //取消 回調(diào)函數(shù)
? ? ? ? confirmCallbackFn:function (){
? ? ? ? ? alert(1);
? ? ? ? }//確認(rèn) 回調(diào)函數(shù)
? ? ? },
? ? ? //其他數(shù)據(jù)
? ? };

在jsx中埋好對應(yīng)的組件結(jié)構(gòu)

<div onClick={()=>(this.alertdialog())}>點擊觸發(fā)彈框</div>
<DialogAlert dialogOpt={this.state.dialogOpt}></DialogAlert>

添加觸發(fā)事件

alertdialog(){
? ? let opts = {
? ? ? alertStatus:true
? ? }
? ? let _dialogOpt = Object.assign(this.state.dialogOpt,opts)
? ? this.setState({
? ? ? dialogOpt:_dialogOpt
? ? })
? }

這樣就完成一個普通的彈框。總感覺這樣寫的一個組件彈框有點冗余,復(fù)用起來也比較麻煩——在state里配置所有自定義的變量,并改動jsx結(jié)構(gòu),還需要注意寫入jsx結(jié)構(gòu)時彈框的層級問題。

接下來我們來實現(xiàn)一種可動態(tài)調(diào)用的組件:

原理是創(chuàng)建一個div,并插入到body里面,用這個div當(dāng)容器,使用render渲染組件,通過改變組件的state來控制組件的顯示和隱藏。

彈框組件:DialogAlert.js

import React, { Component } from 'react';
import ReactDOM from 'react-dom';
import './index.scss';
?
//調(diào)用方法
// DialogAlert.open({
? ? // alertTitle:'提示2',
? ? // alertTip:"頁面加載失敗,是否重新加載?",
? ? // cancelText:'取消',
? ? // confirmText:'重新加載',
? ? // isShortTip:true,
? ? // isShowCancel:true,
? ? // isShowConfirm:true,
? ? // cancelCallbackFn:function(){
? ? // ? console.log('取消了')
? ? // },
? ? // confirmCallbackFn:function (){
? ? // ? console.log("確認(rèn)了...");
? ? // }
// });
?
class DialogBox extends Component {
? ? constructor(props){
? ? ? ? super(props);
? ? ? ? this.state = {
? ? ? ? ? ? alertStatus: false, //是否顯示提示框
?
? ? ? ? ? ? alertTitle:'提示', //標(biāo)題
? ? ? ? ? ? alertTip:'網(wǎng)絡(luò)錯誤', //提示
? ? ? ? ? ? cancelText:'取消',
? ? ? ? ? ? confirmText:'確認(rèn)',
?
? ? ? ? ? ? isShortTip:false, //是否為短提示,短提示的情況下不顯示'取消''確認(rèn)'(且2s后消失),且優(yōu)先級最高,其他配置無效
?
? ? ? ? ? ? isShowCancel:true, //是否顯示確認(rèn)按鈕
? ? ? ? ? ? isShowConfirm:true, //是否顯示確認(rèn)按鈕
?
? ? ? ? ? ? cancelCallbackFn:function(){}, //取消 回調(diào)函數(shù)
? ? ? ? ? ? confirmCallbackFn:function (){}//確認(rèn) 回調(diào)函數(shù)
? ? ? ? }
? ? }
?
? ? //打開提示框
? ? open = (options) => {
? ? ? ? options = options || {};
? ? ? ??
? ? ? ? //如果是短提示
? ? ? ? if(options.isShortTip){
? ? ? ? ? ? options.isShowCancel = false;
? ? ? ? ? ? options.isShowConfirm = false;
? ? ? ? ? ? setTimeout(()=>{
? ? ? ? ? ? ? ? this.close()
? ? ? ? ? ? },2000)
? ? ? ? }
?
? ? ? ? options.alertStatus = true;
? ? ? ? this.setState({
? ? ? ? ? ? ...options
? ? ? ? })
? ? }
? ? //取消
? ? cancel = () => {
? ? ? ? this.state.cancelCallbackFn();
? ? ? ? this.close()
? ? }
? ? //確認(rèn)
? ? confirm = () => {
? ? ? ? this.state.confirmCallbackFn();
? ? ? ? this.close()
? ? }
? ? close = () => {
? ? ? ? this.setState({
? ? ? ? ? ? alertStatus:false
? ? ? ? })
? ? }
?
? ? render(){
? ? ? ? let opts = this.state;
? ? ? ? return (
? ? ? ? ? ? <div className="dialog-wrap" style={opts.alertStatus? {display:'block'}:{display:'none'}}>
? ? ? ? ? ? ? ? <div className="dialog-box">
? ? ? ? ? ? ? ? ? ? <h6>{opts.alertTitle}</h6>
? ? ? ? ? ? ? ? ? ? <p>{opts.alertTip}</p>
? ? ? ? ? ? ? ? ? ? {!opts.isShowCancel && !opts.isShowConfirm ? null : (
? ? ? ? ? ? ? ? ? ? ? ? <div>
? ? ? ? ? ? ? ? ? ? ? ? ? ? {opts.isShowCancel ? (<span onClick={ () => this.cancel() }>{opts.cancelText}</span>) : null}
? ? ? ? ? ? ? ? ? ? ? ? ? ? {opts.isShowConfirm ? (<span className="confirm" onClick={ () => this.confirm() }>{opts.confirmText}</span>) : null}
? ? ? ? ? ? ? ? ? ? ? ? </div>
? ? ? ? ? ? ? ? ? ? ? ? )}
? ? ? ? ? ? ? ? </div>
? ? ? ? ? ? </div>
? ? ? ? )
? ? }
}
?
let div = document.createElement('div');
document.body.appendChild(div);
let DialogAlert = ReactDOM.render(<DialogBox /> ,div); //返回實例
?
export default DialogAlert;

調(diào)用頁面index.js

import DialogAlert from '../../widget/DialogAlert/index';
? ?
//省略了組件的js
?
DialogAlert.open({
? ? alertTip:"加載失敗,是否重新加載?",
? ? confirmText:'重新加載',
? ? cancelCallbackFn:()=>{
? ? ? ? window.history.back();
? ? },
? ? confirmCallbackFn:()=>{
? ? ? ? //todo...
? ? }
})

這里用到了ReactDOM.render,官方文檔說這個方法目前會返回了對根組件實例的引用,所以我們可以調(diào)用到里面的open方法。但是官方文檔中目前應(yīng)該避免使用返回的引用,因為它是歷史遺留下來的內(nèi)容。為了以后的react更新迭代的兼容,我們可以省去動態(tài)插入組件的過程,改為寫在jsx中,并設(shè)置ref,使用this.refs.xxx獲取當(dāng)前組件的實例,以便調(diào)用實例方法。

只需引入之后,直接調(diào)用就可以了。這樣寫的好處是解決了彈框的層級問題,也不用去改動jsx結(jié)構(gòu),其他頁面復(fù)用起來更加方便快捷。

這兩種方法在組件的定義上并沒有很大的不同,只是在更新狀態(tài)的時候有差異。第一種方法是在componentWillReceiveProps這個生命周期中監(jiān)聽父組件的值的變化再更新到state上,第二中方法是直接調(diào)用實例的open方法通過獲取參數(shù)將值更新到state上。

以上就是本文的全部內(nèi)容,希望對大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。

相關(guān)文章

最新評論