Skip to content

Latest commit

 

History

History
643 lines (522 loc) · 23.3 KB

File metadata and controls

643 lines (522 loc) · 23.3 KB

五、React 和 jQuery Bootstrap 组件

到目前为止,我们已经介绍了如何创建 DOM 元素以及 DOM 如何与 React 组件交互。正如我们所看到的,每个框架都有不同的方式与 DOM 元素交互,而 React 使用快速的内部合成 DOM 来执行差异,并为组件实际所在的位置计算最有效的 DOM 变异。

在本章中,我们将了解 jQuery Bootstrap 组件如何在虚拟 DOM 中工作。我们还将讨论以下主题:

  • 组件生命周期方法
  • 组件集成
  • Bootstrap 模式
  • 有细节的例子

这将使您更好地理解如何使用 React 处理 jQuery Bootstrap 组件。

在 Bootstrap 中,我们有许多可重用的组件,使开发人员的生活变得简单。在第一章开始使用 React 和 Bootstrap第二章让我们用 React Bootstrap 和 React构建一个响应主题,我们解释了 Bootstrap 的集成。让我们从一个小组件开始,将其集成到 React 中。

警报

在 Bootstrap 中,我们有alert组件根据用户操作在 UI 中显示消息,从而使组件更具交互性。

首先,我们需要在包含close按钮的.alert类中包含一个文本。

Bootstrap 还提供了上下文类,这些类根据消息表示不同的颜色:

  • .alert-success
  • .alert-info
  • .alert-warning
  • .alert-error

用法

Bootstrap 为我们提供了alert组件的预定义结构,便于将其包含在我们的项目中:

<div class="alert alert-info alert-dismissible fade in" role="alert">
    <button type="button" class="close" data-dismiss="alert"
    aria-label="Close">
    <span aria-hidden="true">&times;</span>
    </button>
</div>

当我们使用close按钮作为包装器标记的子元素时,我们已经声明了alert类,我们需要将.alert-dismissible类添加到该元素中,如前面的示例代码所示。

添加自定义属性data-dismiss="alert"将为我们提供alert中的close功能。

React 中的 Bootstrap 警报组件

现在我们将把 Bootstrap 程序alert组件与我们在第 4DOM 与 ReactJS交互中前面开发的 React 控制组件(textarea集成,在这里我们开发了一个带有控制组件的表单。我们介绍了一个防止用户将文本写入上述textarea字符的示例。

在下面的示例中,我们将看到如何将警报/警告消息与同一组件绑定。这里,我们只是扩展开发的受控组件。

您可能已经在第 4 章中看到了以下屏幕截图,DOM 与 ReactJS的交互,其中显示了在textarea中带有注释的受控组件。在括号中,可以看到定义的字符限制:

Bootstrap alert component in React

添加alert组件后,当用户达到最大字符限制时,会在 UI 中显示。

为此,首先,我们需要将 Bootstrap 组件包含到 React 结构中。让我们来看一个实际例子:

var BootstrapAlert = React.createClass({  
    render: function() { 
        return ( 
            <div className={(this.props.className) + ' alert'}
            role="alert" ref="alertMsg"> 
                <button type="button" className="close"
                data-dismiss="alert" aria-label="Close" onClick=
                {this.handleClose}> 
                <span aria-hidden="true">×</span></button> 
                <strong>Ooops!</strong> You reached the max limit  
            </div>     
        ); 
    } 
}); 

我们已经创建了一个名为BootstrapAlert的组件,并将 HTML 包装在render方法中。

onClick正在调用handleClose函数,该函数将处理close事件。这是 React 的默认函数,因为我们在 JavaScript 中有.show().hide()默认函数。

在集成 jQuery Bootstrap 组件之前,我们必须了解组件中的 React 生命周期方法。

组件生命周期方法

在 React 中,每个组件都有自己特定的回调函数。当我们考虑 DOM 操作或在 React(jQuery)中集成其他插件时,这些回调函数起着重要作用。让我们看看组件生命周期中常用的一些方法:

  • getInitialState():此方法将帮助您获取组件的初始状态。

  • componentDidMount:在 DOM 中首次呈现或挂载组件时,会自动调用此方法。在集成 JavaScript 框架时,我们将使用此方法执行诸如setTimeoutsetInterval之类的操作,或者发送 AJAX 请求。

  • componentWillReceiveProps: This method will be used to receive new props.

    没有替代方法,如componentWillReceiveState。如果我们需要对state更改执行操作,那么我们使用componentWillUpdate

  • componentWillUnmount:在从 DOM 卸载组件之前调用此方法。清理在componentDidMount方法中装入的 DOM 内存元素。

  • componentWillUpdate:在更新新的propsstate之前调用此方法。

  • componentDidUpdate:当组件在 DOM 中被更新时,会立即调用。

组件集成

我们现在了解了组件生命周期方法。现在让我们使用这些方法将我们的组件集成到 React 中。遵守以下代码:

componentDidMount: function() { 
    // When the component is mount into the DOM 
    $(this.refs.alertMsg).hide(); 
          // Bootstrap's alert events 
// functionality. Lets hook into one of them: 
    $(this.refs.alertMsg).on('closed.bs.alert', this.handleClose); 
  }, 
  componentWillUnmount: function() {  
      $(this.refs.alertMsg).off('closed.bs.alert', this.handleClose); 
  }, 
  show: function() { 
      $(this.refs.alertMsg).show(); 
  }, 
  close: function() { 
      $(this.refs.alertMsg).alert('close'); 
  }, 
  hide: function() { 
      $(this.refs.alertMsg).hide(); 
  }, 
  render: function() { 
      return ( 
      <div className={(this.props.className) + ' alert'} role="alert"
      ref="alertMsg"> 
          <button type="button" className="close" data-dismiss="alert"
          aria-label="Close" onClick={this.handleClose}> 
          <span aria-hidden="true">x</span></button> 
          <strong>Oh snap!</strong> You reached the max limit  
      </div>      
    ); 
  }, 
}); 

让我们看看前面代码的解释:

  • 默认情况下,componentDidMount()在组件装入 DOM 时使用refs关键字隐藏alert组件
  • alert组件为我们提供了一些在调用close方法时调用的事件
  • 调用close方法时调用close.bs.alert

当我们使用组件componentWillUnmount时,我们也在使用 jQuery.off删除事件处理程序。当我们单击 close(x)按钮时,它调用 Closehandler 并调用 close

我们还创建了一些控制组件的自定义事件:

  • .hide():用于隐藏组件
  • .show():用于显示组件
  • .close():用于关闭警报

遵守以下代码:

var Teaxtarea = React.createClass({ 
    getInitialState: function() { 
        return {value: 'Controlled!!!', char_Left: max_Char}; 
    }, 
    handleChange: function(event) { 
        var input = event.target.value; 
        this.setState({value: input.substr(0, max_Char),char_Left:   
        max_Char - input.length}); 
        if (input.length == max_Char){ 
            this.refs.alertBox.show(); 
        } 
        else{ 
        this.refs.alertBox.hide(); 
        } 
    }, 
    handleClose: function() { 
        this.refs.alertBox.close(); 
    }, 

    render: function() { 
        var alertBox = null; 
        alertBox = ( 
            <BootstrapAlert className="alert-warning fade in" 
            ref="alertBox" onClose={this.handleClose}/> 
        ); 
        return ( 
            <div className="example"> 
            {alertBox} 
                <div className="form-group"> 
                    <label htmlFor="comments">Comments <span style=
                    {style}>*</span></label(<span{this.state.char_Left}
                    </span> characters left) 
                    <textarea className="form-control" value=
                    {this.state.value} maxLength={max_Char} onChange=
                    {this.handleChange} /> 
                </div> 
            </div> 
        ); 
    } 
}); 
ReactDOM.render( 
    <Teaxtarea />, 
    document.getElementById('alert') 
); 

使用if条件,我们根据字符长度隐藏和显示警报。handleClose()方法将调用我们之前创建的close方法来关闭警报。

render方法中,我们使用className propsref键和onClose道具渲染组件来处理close方法。

当我们关闭警报时,课堂上的.fade给了我们淡入淡出的效果。

现在,让我们结合我们的代码,在浏览器中快速查看:

'use strict'; 
var max_Char='140'; 
var style = {color: "#ffaaaa"}; 

var BootstrapAlert = React.createClass({  
    componentDidMount: function() { 
        // When the component is added 
        $(this.refs.alertMsg).hide();  
        // Bootstrap's alert class exposes a few events for hooking 
        into modal 
        // functionality. Lets hook into one of them: 
        $(this.refs.alertMsg).on('closed.bs.alert', this.handleClose); 
    }, 
    componentWillUnmount: function() { 
        $(this.refs.alertMsg).off('closed.bs.alert', this.
        handleClose); 
    }, 
    show: function() { 
        $(this.refs.alertMsg).show(); 
    }, 
    close: function() { 
        $(this.refs.alertMsg).alert('close'); 
    }, 
    hide: function() { 
        $(this.refs.alertMsg).hide(); 
    },  
    render: function() { 
        return ( 
            <div className={(this.props.className) + ' alert'}
            role="alert" ref="alertMsg"> 
                <button type="button" className="close" 
                data-dismiss="alert" aria-label="Close" onClick=
                {this.handleClose}> 
                <span aria-hidden="true">×</span></button> 
                <strong>oops!</strong> You reached the max limit  
            </div> 

        ); 
    } 
}); 

var Teaxtarea = React.createClass({ 
    getInitialState: function() { 
        return {value: '', char_Left: max_Char}; 
    }, 
    handleChange: function(event) { 
        var input = event.target.value; 
        this.setState({value: input.substr(0, max_Char),char_Left: 
        max_Char - input.length}); 
        if (input.length == max_Char){ 
            this.refs.alertBox.show(); 
        } 
        else{ 
            this.refs.alertBox.hide(); 
        } 
    }, 
    handleClose: function() { 
        this.refs.alertBox.close(); 
    }, 

    render: function() { 
        var alertBox = null; 
        alertBox = ( 
            <BootstrapAlert className="alert-warning fade in"
            ref="alertBox"/> 
        ); 
        return ( 
            <div className="example"> 
            {alertBox} 
                <div className="form-group"> 
                    <label htmlFor="comments">Comments <span style=
                    {style}>*</span></label>(<span
                    {this.state.char_Left}</span> characters left) 
                    <textarea className="form-control" value=
                    {this.state.value} maxLength={max_Char} onChange=
                    {this.handleChange} /> 
                </div> 
            </div> 
        ); 
    } 
}); 
ReactDOM.render( 
    <Teaxtarea />, 
    document.getElementById('alert') 
);

观察以下屏幕截图:

Component integration

当我们点击关闭(x按钮时,它会调用Closehandler并调用close事件来关闭警报消息。一旦关闭,要将其取回,您必须刷新页面。请注意以下屏幕截图:

Component integration

使用console.log(),我们可以验证我们的组件是否已安装或卸载。

现在让我们看一下 Bootstrap 组件的另一个例子。

Bootstrap 模式

Bootstrap 模式组件向用户显示少量信息,而不带您进入新页面。

下表来自 Bootstrap 网站(http://getbootstrap.com/javascript 显示了模式可用选项的完整列表:

| **名称** | **型** | **违约** | **说明** | | `backdrop` | 布尔值 | `true` | `backdrop`允许我们在用户点击外部时关闭模式。它给出了一个`backdrop`的静态值,该值不会在单击时关闭模式。 | | `keyboard` | 布尔值 | `true` | 按*Esc*键关闭模式。 | | `show` | 布尔值 | `true` | 初始化模态。 | | `remote` | 路径 | `false` | 自版本 3.3.0 以来,此选项已被弃用,并已在版本 4 中删除。对于客户端模板,建议使用数据绑定框架,或者自己调用`jQuery.load`。 |

下表来自 Bootstrap 网站(http://getbootstrap.com/javascript 显示了 Bootstrap 模式组件可用事件的完整列表:

| **事件类型** | **说明** | | `show.bs.modal` | 调用`show`(`$('.modal').show();`实例方法时,此事件立即激发。 | | `shown.bs.modal` | 此事件在模式对用户可见时触发(我们需要等待 CSS 转换完成)。 | | `hide.bs.modal` | 调用`hide`(`$('.modal').hide();`实例方法后,立即触发此事件。 | | `hidden.bs.modal` | 当模式对用户完成隐藏时(我们需要等待 CSS 转换完成),将触发此事件。 | | `loaded.bs.modal` | 当模式使用`remote`选项加载内容时,将触发此事件。 |

无论何时集成任何其他组件,我们都必须了解库或插件提供的组件选项和事件。

首先,我们需要创建一个button组件来打开一个modal弹出窗口:

// Bootstrap's button to open the modal 
var BootstrapButton = React.createClass({ 
    render: function() { 
        return ( 
            <button {...this.props} 
            role="button" 
            type="button" 
            className={(this.props.className || '') + ' btn'} /> 
        ); 
    } 
}); 

现在,我们需要创建一个modal-dialog组件,并将buttondialog组件装载到 DOM 中。

我们还将创建一些处理showhide模式事件的事件:

var BootstrapModal = React.createClass({ 
    componentDidMount: function() { 
        // When the component is mount into the DOM 
        $(this.refs.root).modal({keyboard: true, show: false}); 

        // capture the Bootstrap's modal events 
        $(this.refs.root).on('hidden.bs.modal', this.handleHidden); 
    }, 
    componentWillUnmount: function() { 
        $(this.refs.root).off('hidden.bs.modal', this.handleHidden); 
    }, 
    close: function() { 
        $(this.refs.root).modal('hide'); 
    }, 
    open: function() { 
        $(this.refs.root).modal('show'); 
    }, 
    render: function() { 
        var confirmButton = null; 
        var cancelButton = null; 

    if (this.props.confirm) { 
        confirmButton = ( 
            <BootstrapButton 
                onClick={this.handleConfirm} 
                className="btn-primary"> 
                {this.props.confirm} 
            </BootstrapButton> 
        ); 
    } 
    if (this.props.cancel) { 
        cancelButton = ( 
            <BootstrapButton onClick={this.handleCancel} className=
            "btn-default"> 
            {this.props.cancel} 
            </BootstrapButton> 
        ); 
    } 

    return ( 
        <div className="modal fade" ref="root"> 
        <div className="modal-dialog"> 
        <div className="modal-content"> 
        <div className="modal-header"> 
        <button 
            type="button" 
            className="close" 
            onClick={this.handleCancel}> 
            &times; 
        </button> 
        <h3>{this.props.title}</h3> 
        </div> 
        <div className="modal-body"> 
            {this.props.children} 
        </div> 
        <div className="modal-footer"> 
            {cancelButton} 
            {confirmButton} 
</div> 
</div> 
</div> 
</div> 
    ); 
  }, 
  handleCancel: function() { 
      if (this.props.onCancel) { 
          this.props.onCancel(); 
      } 
  }, 
  handleConfirm: function() { 
      if (this.props.onConfirm) { 
          this.props.onConfirm(); 
      } 
  }, 
  handleHidden: function() { 
      if (this.props.onHidden) { 
          this.props.onHidden(); 
      } 
  } 
}); 

componentDidMount()中,我们正在使用一些选项初始化modal组件,并将hidden.bs.modal事件注入modal

close()show()功能触发hide/show模型事件。

render()方法中,我们使用propsref键包含模式 HTML 模板来操作模板。

handleCancel()handleConfirm()handleHidden()处理我们组件的每个状态。

.modal-*课程赋予我们 Bootstrap 的风格,让我们的应用程序更加人性化。

现在我们需要使用render函数渲染组件:

var ReactBootstrapModalDialog = React.createClass({ 
    handleCancel: function() { 
        if (confirm('Are you sure you want to cancel the dialog 
        info?')) { 
            this.refs.modal.close(); 
        } 
    }, 
    render: function() { 
        var modal = null; 
        modal = ( 
            <BootstrapModal 
                ref="modal" 
                confirm="OK" 
                cancel="Cancel" 
                onCancel={this.handleCancel} 
                onConfirm={this.closeModal} 
                onHidden={this.handleModalDidClose} 
                > 
                This is a React component powered by jQuery and                      Bootstrap! 
            </BootstrapModal> 
        ); 
        return ( 
            {modal} 
            <BootstrapButton onClick={this.openModal} className="btn-
            default"> 
            Open modal 
            </BootstrapButton> 
        ); 
    }, 
    openModal: function() { 
        this.refs.modal.open(); 
    }, 
    closeModal: function() { 
        this.refs.modal.close(); 
    }, 
    handleModalDidClose: function() { 
        alert("The modal has been dismissed!"); 
    } 
}); 

我们在<BootstrapModal>中通过props并渲染<BootstrapButton>

使用this关键字,我们调用一个函数来调用modal事件,并在每个事件火灾时显示警报:

ReactDOM.render(<ReactBootstrapModalDialog />, 
document.getElementById('modal')); 

让我们快速浏览浏览器中的组件:

Bootstrap modal

哎呀!我们得到了一个错误。我认为这可能是因为我们没有将组件包装在render方法中。它应始终使用一个父元素进行换行:

return ( 
    <div className="modalbtn"> 
        {modal} 
    <BootstrapButton onClick={this.openModal} className="btn-default"> 
        Open modal 
    </BootstrapButton> 
    </div> 
); 

下面是我们的ReactBootstrapModalDialog组件在做了一个小改动后的样子:

var ReactBootstrapModalDialog = React.createClass({ 
    handleCancel: function() { 
        if (confirm('Are you sure you want to cancel?')) { 
            this.refs.modal.close(); 
        } 
    }, 
    render: function() { 
        var modal = null; 
        modal = ( 
            <BootstrapModal 
                ref="modal" 
                confirm="OK" 
                cancel="Cancel" 
                onCancel={this.handleCancel} 
                onConfirm={this.closeModal} 
                onHidden={this.handleModalDidClose} 
                > 
                This is a React component powered by jQuery and
                Bootstrap! 
            </BootstrapModal> 
        ); 
        return ( 
            <div className="modalbtn"> 
                {modal} 
                <BootstrapButton onClick={this.openModal} 
                className="btn-default"> 
                    Open modal 
                </BootstrapButton> 
            </div> 
        ); 
    }, 
    openModal: function() { 
        this.refs.modal.open(); 
    }, 
    closeModal: function() { 
        this.refs.modal.close(); 
    }, 
    handleModalDidClose: function() { 
        alert("The modal has been dismissed!"); 
    } 
}); 

ReactDOM.render(<ReactBootstrapModalDialog />, document.getElementById('modal')); 

让我们在浏览器中再次查看我们的组件:

Bootstrap modal

现在点击打开模态按钮,可以看到模态对话框:

Bootstrap modal

如果点击取消确定按钮,将显示如下屏幕截图所示的警报框:

Bootstrap modal

如果我们点击X图标,它将显示警报框,如下图所示:

Bootstrap modal

现在我们知道,我们可以通过点击(X图标来关闭模态对话框。

当模态对话框关闭时,显示警报,**模态已解除!**请参见以下截图:

Bootstrap modal

下面是我们的 HTML 文件的外观:

<!DOCTYPE html>
<html>
    <head>
        <meta charset="UTF-8" />
        <title>J-Query Bootstrap Component with React</title>
        <link rel="stylesheet" href="css/bootstrap.min.css">
    </head>
    <body>
        <div class="container">
            <div class="row">
                <div class="col-sm-6">
                    <h2>jQuery Bootstrap Modal with React</h2>
                    <hr/>
                    <div id="modal">
                    </div>
                </div>
            </div>
        </div>
        <script type="text/javascript" src="js/jquery-1.10.2.min.js">
        </script>
        <script type="text/javascript" src="js/bootstrap.min.js">
        </script>
        <script type="text/javascript" src="js/react.min.js"></script>
        <script type="text/javascript" src="js/react-dom.min.js">
        </script>
        <script src="js/browser.min.js"></script>
        <script src="component/modal.js" type="text/babel"></script>
    </body>
</html>

总结

我们已经了解了如何在 React 中集成 jQuery Bootstrap 组件,以及在集成任何第三方插件(如 jQuery)时生命周期方法是如何工作的。

我们能够用处理事件的道具检查组件状态,并用适当的内容显示对话框。我们还研究了生命周期方法如何帮助我们集成其他第三方插件。

我们现在了解了组件生命周期方法以及它们在 React 中的工作方式。我们已经学习了如何在 React 中集成 jQuery 组件。我们已经看到了事件处理机制以及警报和模式组件的示例。

本章中显示的关键示例将帮助您理解或澄清在 React 中集成 jQuery Bootstrap 组件的概念。

让我们继续看第 6 章Redux 架构,这是关于在 React 中使用 Redux 架构的。