• 首页 首页 icon
  • 工具库 工具库 icon
    • IP查询 IP查询 icon
  • 内容库 内容库 icon
    • 快讯库 快讯库 icon
    • 精品库 精品库 icon
    • 问答库 问答库 icon
  • 更多 更多 icon
    • 服务条款 服务条款 icon

面试题React实现Dialog模板

武飞扬头像
愤怒的小火柴人
帮助1


前言

题目大概是要实现一个dialog的模板,你可以应用他实现很多功能,比如说某个操作的确认提醒等,我们要做的实现这样一个可应用都多个功能的dialog,只要你想要显示的组件写好,外部嵌套这样一个dialog组件,就能实现

一、简单Dialog实现

首先我们先实现一个简单的Dialog
不妨百度一下antd的对话框Modal
功能如下:

1.点击出现,周围灰色,中间一个对话框,点击周围关闭对话框,点击对话框不会关闭
2.这里注意,当对话框出现,原本页面其他事件点击都不会被触发

思路:
很简单,设置一个状态,isShow来表示dialog是否出现,页面添加一个按钮(其他的也可以,目的是触发dialog出现),初始化dialogfalse,点击变为true,此时出现的dialog会覆盖整个页面,给这个覆盖了整个页面的dialog_box挂载点击事件,监听如果点击的周围灰色区域,则再把isShow设为false,关闭dialog

1.react-redux存储状态isShow

这个状态可能会被很多地方使用,所以直接redux存储,
步骤:

1.下载安装react-redux和redux yarn add redux react-redux
2.创建store
3.创建reducer
4.<Provider></Provider>包裹<App/> 并传入参数 store={store}


代码如下:
首先整体目录:
学新通
store.js
这里使用了combineReducers,主要是熟悉一下,好久不用总要看一眼

import {combineReducers, createStore} from 'redux'
import  dialogReducer  from "./reducer/dialogReducer";
const reducer=combineReducers({
    dialogReducer
})

const store=createStore(reducer)

export default store

dialogReducer.js

var dialogReducer=(prevState={
    isShow:false,
},action)=>{
    var state={...prevState};
    switch(action.type){
        case 'DIALOG_SHOW':{
            return {
                ...state,
                isShow:action.value,
            }
        }
        default:{
            return state
        }
    }
}

export default dialogReducer

index.js

import React from 'react';
import ReactDOM from 'react-dom/client';
import { Provider } from 'react-redux';
import store from './redux/store'

import App from './App';
import reportWebVitals from './reportWebVitals';

const root = ReactDOM.createRoot(document.getElementById('root'));
root.render(
  <React.StrictMode>
   <Provider store={store}>
   <App />
   </Provider>
  </React.StrictMode>
);

// If you want to start measuring performance in your app, pass a function
// to log results (for example: reportWebVitals(console.log))
// or send to an analytics endpoint. Learn more: https://bit.ly/CRA-vitals
reportWebVitals();

2.创建Dialog组件

这里有一步监听是否是dialog对话框还是周围灰色区域,大致如下操作:

1.创建一个refuseRef创建),挂载到整个Dialog上,这样就能获取到整个dialog_box组件,
学新通

学新通

2.然后添加监听事件,以及出发的处理函数,这个处理函数是要判断当前点击的组件的class类名是否是dialog_box(因为这个点击会精确到具体组件,即点击子组件会返回子组件)
首先,节点及其类名如下:
学新通
添加监听
学新通
这里函数dialogFun的参数e是当前点击到的组件,如果是灰色区域,则返回整体dialog_box,点击中间对话框,则返回dialog,然后可以通过e.target.className获取组件类名用于比较,这里props.close()是将isShow设为false的操作,具体定义放在了父组件App
所以综上:

ref用来添加监听事件
e.target用来监听点击到的组件
注意ref.current可以获取被挂载的组件,e.target.className可以获去class类名


代码如下
App.js
这是一个全局的父组件,所以我直接将处理显示的函数放在了这里然后传递给子组件,这样子组件就不需要再connect获取redux中的状态
(下面<Dialog></Dialog>组件中的嵌套可以先忽略)

import React,{useEffect} from 'react'
import { connect } from 'react-redux'
import Dialog from './components/Dialog'
import './App.css'
import DialogCancle from './components/DialogCancle'

function App(props) {
    const close=function(){
        props.changeShow(false)
    }
  useEffect(() => {
    console.log(props.isShow)
  }, [props.isShow])
  return (
    <div style={{height:'100vh',width:'100vw'}}>App
        <button onClick={()=>{props.changeShow(true)}}>吃点什么</button>
                {props.isShow?<Dialog close={close}><DialogCancle close={close}/></Dialog>:''}
    </div>
  )
}

const mapStateToProps=function(state){
    return {
        isShow:state.dialogReducer.isShow,
    }
}
const mapStateToDispatch=function(dispatch){
    return {
        changeShow(isShow){
            dispatch({type:"DIALOG_SHOW",value:isShow})
        }
    }
}
export default connect(mapStateToProps,mapStateToDispatch)(App)

Dialog.js

import React,{useRef,useEffect} from 'react';
import './Dialog.css'

export default function Dialog(props) {
    useEffect(() => {
       ref.current.addEventListener('click',dialogFun)
    }, [props.isShow])
    const dialogFun=function(e){
        console.log(ref.current)
        if(e.target.className==='dialog_box'){
           props.close()
        }
    }
    var ref=useRef()
    return (
    <div  value="dialog_box" ref={ref} className="dialog_box">
        <div value="dialog" className="dialog">
            <div style={{textAlign:'center',color:'#1890FF',fontSize:'18px',paddingTop:'10px',paddingBottom:'10px'}}>Dialog</div>
            <div >
               {props.children}
            </div>
        </div>
    </div>
    
  );
}

Dialog.css
css代码可以自定义,我就随便写了些,主要不要忘了zIndex的值要大于原本页面,不然无法覆盖

.dialog{

    /* border-radius: 10px; */
    background-color: white;
    height:150px;
    width:400px;
    margin:0 auto;
    margin-top:100px;
    transition: 3s linner;
}
.dialog_box{
    width:100%;
    height:100%;
    position:fixed;
    z-index:10001;
    top:0;
    left:0;
    background-color: rgba(3,3,3,0.4);
    /* opacity: 0.4; */
}

学新通

到此简单的Dialog他已经完成,接下来我们要实现一个中间传入组件就能显示在Dialog里面的功能

二、组件嵌套

看了网上,有很多实现方法,比如render什么的,这里使用插槽,但一直没找到怎么往插槽里直接传参,失败
直接在<Dialog></Dialog>组件内部添加一个{props.children}用来占位置,这时你只需将你想要显示的子组件外部嵌套一层Dialog组件即可

<Dialog close={close}>
	<DialogCancle close={close}/>
</Dialog>

Dialog组件的内部render

return (
    <div  value="dialog_box" ref={ref} className="dialog_box">
        <div value="dialog" className="dialog">
            <div style={{textAlign:'center',color:'#1890FF',fontSize:'18px',paddingTop:'10px',paddingBottom:'10px'}}>Dialog</div>
            <div >
               {props.children}
            </div>
        </div>
    </div>
    
  );

简单到不能再简单的子组件DialogCancle

import React,{useEffect} from 'react'
import Dialog from './Dialog'
export default function DialogCancle(props) {
   useEffect(() => {
    console.log(props)
   }, [])
  return (
    <div >
        <p>今天中午吃什么??</p>
        <button>不吃饭</button>
        <button onClick={()=>props.close()} >取消</button>
    </div>
  )
}

学新通
所以无论你的DialogCancle内部怎么写,只要你外部嵌套Dialog,就可以将组件内容显示再对话框内

十分粗糙的实现这个样一个小demo,有问题请指出

这篇好文章是转载于:学新通技术网

  • 版权申明: 本站部分内容来自互联网,仅供学习及演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,请提供相关证据及您的身份证明,我们将在收到邮件后48小时内删除。
  • 本站站名: 学新通技术网
  • 本文地址: /boutique/detail/tanhfkibjb
系列文章
更多 icon
同类精品
更多 icon
继续加载