1. 程式人生 > >react全局的公共組件-------彈框

react全局的公共組件-------彈框

idt tran toa xtend 引入 imp turn sna position

最近研究react,發現寫一個組件很容易,但是要寫一個全局的好像有點麻煩。不能像VUE一樣,直接在原型上面擴展,註冊全局組件

下面實現一個彈框,只需要引入之後,直接調用方法即可,不需要寫入組件

給出我寫react全局組件的思路。

創建一個 div加入到body,用這個div當容器,渲染react組件,然後由改變組件的 state來控制彈框的顯示隱藏

代碼結構如下:

技術分享圖片

效果圖如下:

技術分享圖片

alert.jsx

import React, { Component } from ‘react‘;
import { is, fromJS } from ‘immutable‘;
import ReactDOM from ‘react-dom‘;
import ReactCSSTransitionGroup from ‘react-addons-css-transition-group‘;
import ‘./alert.css‘;


class Alert extends Component{

  state = {
    alertStatus:false,
    alertTip:"提示",
    closeAlert:function(){}
  };
  // css動畫組件設置為目標組件
  FirstChild = props => {
    const childrenArray = React.Children.toArray(props.children);
    return childrenArray[0] || null;
  }
  // 關閉彈框
  confirm = () => {
    this.setState({
      alertStatus:false
    })
    this.state.closeAlert();
  }
  
  shouldComponentUpdate(nextProps, nextState){
    return !is(fromJS(this.props), fromJS(nextProps)) || !is(fromJS(this.state), fromJS(nextState))
  }
  
  render(){
    return (
      <ReactCSSTransitionGroup
        component={this.FirstChild}
        transitionName=‘hide‘
        transitionEnterTimeout={300}
        transitionLeaveTimeout={300}>
        <div className="alert-con" style={this.state.alertStatus? {display:‘block‘}:{display:‘none‘}}>
          <div className="alert-context">
            <div className="alert-content-detail">{this.state.alertTip}</div>
            <div className="comfirm" onClick={this.confirm}>確認</div>
          </div>
        </div>
      </ReactCSSTransitionGroup>
    );
  }
}

let div = document.createElement(‘div‘);
let props = {
  
};
document.body.appendChild(div);

let Box = ReactDOM.render(React.createElement(
  Alert,
  props
),div);

let defaultState = {
  alertStatus:false,
  alertTip:"提示",
  closeAlert:function(){}
}

export default {
  open(options){
    options = options || {};
    options.alertStatus = true;

    Box.setState({
      ...defaultState,
      ...options
    })
  },
  close(){
    Box.setState({
      ...defaultState
    })
  }
}

  

 

alert.css

.alert-con {
  position: fixed;
  top: 0;
  left: 0;
  width: 100%;
  height: 100%;
  background: rgba(0, 0, 0, 0.3);
  z-index: 11;
}
.alert-context {
  background-color: #fff;
  border-radius: 16px;
  height: 200px;
  width: 80%;
  margin: 40% auto 0;
}
.alert-context .alert-content-detail {
  text-align: center;
  color: #333;
  font-size: 24px;
  height: 150px;
  line-height: 150px;
}
.alert-context .comfirm {
  border-top: 1PX solid #eee;
  box-sizing: border-box;
  height: 50px;
  line-height: 50px;
  text-align: center;
  font-size: 20px;
  color: #666;
}
.alert-enter {
  opacity: 0;
}
.alert-enter.alert-enter-active {
  transition: all 300ms;
  opacity: 1;
}
.alert-leave {
  opacity: 1;
}
.alert-leave.alert-leave-active {
  transition: all 300ms;
  opacity: 0;
}

  

使用方式:

import React, { Component } from ‘react‘;

import Alert from "../components/alert/alert.jsx";

class Two extends Component {
	constructor(props){
		super(props);
		this.state = {
			num:1
		};
	}

	open=()=>{
		Alert.open({
			alertTip:"這是一個測試彈框",
			closeAlert:function(){
				console.log("關閉了...");
			}
		});
	}
  render() {
    return (
       <div className="Two">
        	Two
		<button onClick={this.open}>
			 開啟寶藏
		</button>	
        	<div>{this.state.num}</div>
       </div>
    );
  }
}

export default Two;

上面直接引入 alert.jsx之後,調用 open函數即可

這樣的好處,解決了彈框的層級問題,使用更加方便快捷

react全局的公共組件-------彈框