面试题React实现Dialog模板
前言
题目大概是要实现一个dialog的模板,你可以应用他实现很多功能,比如说某个操作的确认提醒等,我们要做的实现这样一个可应用都多个功能的dialog,只要你想要显示的组件写好,外部嵌套这样一个dialog组件,就能实现
一、简单Dialog实现
首先我们先实现一个简单的Dialog
不妨百度一下antd的对话框Modal
功能如下:
1.点击出现,周围灰色,中间一个对话框,点击周围关闭对话框,点击对话框不会关闭
2.这里注意,当对话框出现,原本页面其他事件点击都不会被触发
思路:
很简单,设置一个状态,isShow
来表示dialog
是否出现,页面添加一个按钮(其他的也可以,目的是触发dialog
出现),初始化dialog
为false
,点击变为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.创建一个ref
(useRef
创建),挂载到整个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
-
photoshop保存的图片太大微信发不了怎么办
PHP中文网 06-15 -
《学习通》视频自动暂停处理方法
HelloWorld317 07-05 -
Android 11 保存文件到外部存储,并分享文件
Luke 10-12 -
word里面弄一个表格后上面的标题会跑到下面怎么办
PHP中文网 06-20 -
photoshop扩展功能面板显示灰色怎么办
PHP中文网 06-14 -
微信公众号没有声音提示怎么办
PHP中文网 03-31 -
excel下划线不显示怎么办
PHP中文网 06-23 -
excel打印预览压线压字怎么办
PHP中文网 06-22 -
怎样阻止微信小程序自动打开
PHP中文网 06-13 -
TikTok加速器哪个好免费的TK加速器推荐
TK小达人 10-01