最近在用react开发项目,遇到一个需求——开发一个弹框组件。在react中创建一个组件是很简单的,只需要使用class创建并引入就可以了,但是要做到可以用js调用这个组件而不是写在jsx结构里,那就需要用到ReactDOM.render这个方法了。
首先先来屡一下需求:
-
弹框里的可配置字段:标题文字,提示文字,确认和取消按钮的显示隐藏以及文字。
-
点击确认和取消按钮后,可以触发相应的事件。
-
是否为短提示,短提示的时候,确认和取消按钮隐藏,并且2s后消失。
接下来用两种方法创建一个弹框组件,并比较一下这两种的差异。
下面先来实现一个普通的写在jsx结构里的组件:
弹框组件:DialogAlert.js
import React, { Component } from 'react';
import './index.scss';
class DialogAlert extends Component {
constructor(props){
super(props);
this.state = {
alertStatus:false,
alertTitle:'提示', //标题
alertTip:'网络错误', //提示
cancelText:'取消',
confirmText:'确认',
isShortTip:false, //是否为短提示,短提示的情况下不显示'取消''确认'(且2s后消失),且优先级最高,其他配置无效
isShowCancel:true, //是否显示确认按钮
isShowConfirm:true, //是否显示确认按钮
cancelCallbackFn:function(){}, //取消 回调函数
confirmCallbackFn:function (){}//确认 回调函数
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()
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 : (
{opts.isShowCancel ? (<span onClick={ () => this.cancel() }>{opts.cancelText}</span>) : null}
{opts.isShowConfirm ? (<span className="confirm" onClick={ () => this.confirm() }>{opts.confirmText}</span>) : null}
export default DialogAlert;
这里的数据更新用到了componentWillReceiveProps这个生命周期,当props发生变化时执行,初始化render时不执行,在这个回调函数里面,你可以根据属性的变化,通过调用this.setState()来更新你的组件状态,旧的属性还是可以通过this.props来获取,这里调用更新状态是安全的,并不会触发额外的render调用。
调用页面index.js
在state中定义可配置字段的变量
import DialogAlert from '../../widget/DialogAlert/index';
//省略了组件的js
this.state = {
dialogOpt:{
alertStatus:false,
alertTip:'我是自定义的内容',
cancelText:'取消2',
confirmText:'确认2',
isShortTip:false,
isShowCancel:true, //是否显示确认按钮
isShowConfirm:true, //是否显示确认按钮
cancelCallbackFn:function(){
alert(0);
}, //取消 回调函数
confirmCallbackFn:function (){
alert(1);
}//确认 回调函数
//其他数据
在jsx中埋好对应的组件结构
<div onClick={()=>(this.alertdialog())}>点击触发弹框</div>
<DialogAlert dialogOpt={this.state.dialogOpt}></DialogAlert>
添加触发事件
alertdialog(){
let opts = {
alertStatus:true
let _dialogOpt = Object.assign(this.state.dialogOpt,opts)
this.setState({
dialogOpt:_dialogOpt
这样就完成一个普通的弹框。总感觉这样写的一个组件弹框有点冗余,复用起来也比较麻烦——在state里配置所有自定义的变量,并改动jsx结构,还需要注意写入jsx结构时弹框的层级问题。
接下来我们来实现一种可动态调用的组件:
原理是创建一个div,并插入到body里面,用这个div当容器,使用render渲染组件,通过改变组件的state来控制组件的显示和隐藏。
弹框组件:DialogAlert.js
import React, { Component } from 'react';
import ReactDOM from 'react-dom';
import './index.scss';
//调用方法
// DialogAlert.open({
// alertTitle:'提示2',
// alertTip:"页面加载失败,是否重新加载?",
// cancelText:'取消',
// confirmText:'重新加载',
// isShortTip:true,
// isShowCancel:true,
// isShowConfirm:true,
// cancelCallbackFn:function(){
// console.log('取消了')
// },
// confirmCallbackFn:function (){
// console.log("确认了...");
// });
class DialogBox extends Component {
constructor(props){
super(props);
this.state = {
alertStatus: false, //是否显示提示框
alertTitle:'提示', //标题
alertTip:'网络错误', //提示
cancelText:'取消',
confirmText:'确认',
isShortTip:false, //是否为短提示,短提示的情况下不显示'取消''确认'(且2s后消失),且优先级最高,其他配置无效
isShowCancel:true, //是否显示确认按钮
isShowConfirm:true, //是否显示确认按钮
cancelCallbackFn:function(){}, //取消 回调函数
confirmCallbackFn:function (){}//确认 回调函数
//打开提示框
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()
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 : (
{opts.isShowCancel ? (<span onClick={ () => this.cancel() }>{opts.cancelText}</span>) : null}
{opts.isShowConfirm ? (<span className="confirm" onClick={ () => this.confirm() }>{opts.confirmText}</span>) : null}
let div = document.createElement('div');
document.body.appendChild(div);
let DialogAlert = ReactDOM.render(<DialogBox /> ,div); //返回实例
export default DialogAlert;
调用页面index.js
import DialogAlert from '../../widget/DialogAlert/index';
//省略了组件的js
DialogAlert.open({
alertTip:"加载失败,是否重新加载?",
confirmText:'重新加载',
cancelCallbackFn:()=>{
window.history.back();
confirmCallbackFn:()=>{
//todo...
这里用到了ReactDOM.render,官方文档说这个方法目前会返回了对根组件实例的引用,所以我们可以调用到里面的open方法。但是官方文档中目前应该避免使用返回的引用,因为它是历史遗留下来的内容。为了以后的react更新迭代的兼容,我们可以省去动态插入组件的过程,改为写在jsx中,并设置ref,使用this.refs.xxx获取当前组件的实例,以便调用实例方法。
只需引入之后,直接调用就可以了。这样写的好处是解决了弹框的层级问题,也不用去改动jsx结构,其他页面复用起来更加方便快捷。
这两种方法在组件的定义上并没有很大的不同,只是在更新状态的时候有差异。第一种方法是在componentWillReceiveProps这个生命周期中监听父组件的值的变化再更新到state上,第二中方法是直接调用实例的open方法通过获取参数将值更新到state上。
最近在用react开发项目,遇到一个需求——开发一个弹框组件。在react中创建一个组件是很简单的,只需要使用class创建并引入就可以了,但是要做到可以用js调用这个组件而不是写在jsx结构里,那就需要用到ReactDOM.render这个方法了。首先先来屡一下需求:弹框里的可配置字段:标题文字,提示文字,确认和取消按钮的显示隐藏以及文字。 点击确认和取消按钮后,可以触发相应的事件。...
import showOdinDialog from '@/components/OdinDialog'
import DetailForm from './detail-form'
// 新增,在onclick方法中:
showOdinDialog
题目:在页面上有一个按钮,点击按钮出现一个旋转的loading,提交按钮不可点击,等待一秒后弹框显示提交失败或者提交成功,接下来我们直接开始
在此之前,我相信您已经安装好了react运行环境,如何创建react工程我就不再赘述,首先我们分析这个题目,按钮,弹框,两个子类组件,然后建一个父类来提供他们数据交流,接下来我们创建一个工程:
1.创建工程 first2react(项目名称):
2.在sr...
基本思路就是:
(1)弹窗组件的显示和隐藏由SelectCityDialog内部一个变量visable来控制,而这个值为true或者false则是由我们传入的值来控制。也就是说父组件传值给SelectCityDialog控制显示和隐藏
(2)由于我们要在外部(父组件)来打开这个弹窗,所以我们要在外部定义一个变量比如我们就叫vis,它每次值的变化则会传递给SelectCi
React开发一个通过方法调用的弹框组件
常见的函数调用的组件有toast,loading等,今天来详细介绍下方法调用的弹框组件,该组件为自定义内容组件,需要展示什么可自行写入,这里仅展示思路和单一的业务ui。
调用时支持的全部传参:title, content,okbtn,marginTop,hasBottom,styles,showX,timeout
- title:标题
- content: 内容,
- okbtn:确定/关闭按钮
- marginTop : 距离顶部的距离
- hasBottom
最好连接上一篇文章一起查看,能更好的理解该文章:
react生命周期函数执行过程:
https://editor.csdn.net/md?not_checkout=1&articleId=109010693
1、constructor(props)
React组件的构造函数在挂载之前被调用。在实现React.Component构造函数时,需要先在添加其他内容前,调用super(props),用来将父组件传来的props绑定到这个类中,使用this.props将会得到。
官方建议不要在construc
react没有slot插槽,但是可以直接通过{{props.children}}获取父组件标签中的内容
import React, { Component, useEffect } from 'react';
import { createPortal } from 'react-dom';
import CSSTransition from 'react-transition-group/CSSTransition';
import { Scrollbars } from 'reac
function LoginForm() {
const [username, setUsername] = useState('');
const [password, setPassword] = useState('');
const handleSubmit = (event) => {
event.preventDefault();
// 这里可以添加登录逻辑
return (
<form onSubmit={handleSubmit}>
<label>
<input
type="text"
value={username}
onChange={(event) => setUsername(event.target.value)}
</label>
<label>
<input
type="password"
value={password}
onChange={(event) => setPassword(event.target.value)}
</label>
<button type="submit">登录</button>
</form>
export default LoginForm;
在上面的代码中,我们使用了 React 的 useState hook 来管理表单中的用户名和密码的状态。当用户在输入框中输入信息时,通过调用 setUsername 和 setPassword 函数来更新状态。
在表单提交时,我们使用了 handleSubmit 函数来阻止默认的提交行为,并在函数内部添加登录逻辑。
这就是 React 中实现用户登录组件的简单方法。希望这对你有所帮助。