【澳门葡京】高阶组件入门介绍,native自定义组件

Modal组件

长途电话不多说,接下去让大家来入手完成一个react Modal组件。

大家先来看一下实效

类型概述

该类型为react练习demo,源代码点击那里,主要涉嫌内容

  1. 组件props与组件样式className
  2. 组件内传四个子节点难题
  3. 因此ref使用真实dom
  4. state状态退换渲染组件
  5. props属性校验

以上为react中基础部分,项目统一筹划图如下所示,具体项目体现可点此处

澳门葡京 1

剧情呈现

点击编辑按键后,左侧凸显组件会形成内容编排组件,那里能够须求三个boolean类型值,根据该值决定浮现内容组件还是编辑内容组件

澳门葡京 2

剧情编排

react
native在app开垦上的三个优势正是组件化开采,当有了拾足多的自定义组件后,能够很有益于的将那么些零部件拼装起来,开采功效进步广大。本文大校以1个picker为例子,来讲如何包装三个通用性很强的react
native组件。本文的示范源码能够在ReactNativeUIComponents下载。这么些类型前景会不停的护卫投入越多实用的组件,也力求这些连串能够看成三个react
native的示范项目,包括了react native开拓中常用的router,navigator,code
push等,可以看做参考。

React 高阶组件入门介绍,react高阶组件入门

高阶组件的定义

HoC 不属于 React 的
API,它是一种实现方式,本质上是2个函数,接受一个或五个 React
组件作为参数,再次来到二个簇新的 React
组件,而不是改建现存的零部件,那样的零部件被号称高阶组件。开采进度中,有的职能须求在六个零部件类复用时,那时能够创制3个Hoc。

骨干用法

包装方式

const HoC = (WrappendComponent) => {
 const WrappingComponent = (props) => (
  <div className="container">
   <WrappendComponent {...props} />
  </div>
 );
 return WrappingComponent;
};

上述代码中,接受 WrappendComponent 作为参数,此参数正是将要被 HoC
包装的常备组件,在 render 中封装贰个 div,赋予它 className
属性,最后发生的 WrappingComponent 和 传入的 WrappendComponent
是四个精光两样的零件。

在 WrappingComponent 中,能够读取、增添、编辑、删除传给
WrappendComponent 的 props,也能够用任何成分包裹
WrappendComponent,用来落成封装样式、增添布局或别的操作。

【澳门葡京】高阶组件入门介绍,native自定义组件。构成格局

const HoC = (WrappedComponent, LoginView) => {
 const WrappingComponent = () => {
  const {user} = this.props; 
  if (user) {
   return <WrappedComponent {...this.props} />
  } else {
   return <LoginView {...this.props} />
  }
 };
 return WrappingComponent;
};

上述代码中有四个零件,WrappedComponent 和 LoginView,假如传入的 props
中留存 user,则符合规律展现的 WrappedComponent 组件,不然突显 LoginView
组件,让用户去登六。HoC
传递的参数可感觉多少个,传递两个零件定制新组件的一颦一笑,例如用户登入状态下显得主页面,未登入展现登陆分界面;在渲染列表时,传入
List 和 Loading 组件,为新组件增加加载中的行为。

一连格局

const HoC = (WrappendComponent) => {
 class WrappingComponent extends WrappendComponent {
  render() (
   const {user, ...otherProps} = this.props;
   this.props = otherProps;
   return super.render();
  }
 }
 return WrappingComponent;
};

WrappingComponent 是一个新组件,它继续自
WrappendComponent,共享父级的函数和质量。能够接纳 super.render() 只怕super.component威尔Update()
调用父级的生命周期函数,然则如此会让三个零部件耦合在1块儿,下降组件的复用性。

React
中对组件的卷入是依据最小可用单元的思辨来开始展览包装的,理想图景下,1个组件只做壹件事情,符合
OOP
中的单一职分规范。固然急需对组件的效应巩固,通过结合的艺术只怕加上代码的艺术对组件举办加强,而不是修改原有的代码。

注意事项

毫无在 render 函数中利用高阶组件

render() {
 // 每一次render函数调用都会创建一个新的EnhancedComponent实例
 // EnhancedComponent1 !== EnhancedComponent2
 const EnhancedComponent = enhance(MyComponent);
 // 每一次都会使子对象树完全被卸载或移除
 return <EnhancedComponent />;
}

React 中的 diff
算法会相比新旧子对象树,确定是否更新现存的子对象树或舍弃现成的子树一视同仁复挂载。

必须将静态方法做拷贝

// 定义静态方法
WrappedComponent.staticMethod = function() {/*...*/}
// 使用高阶组件
const EnhancedComponent = enhance(WrappedComponent);

// 增强型组件没有静态方法
typeof EnhancedComponent.staticMethod === 'undefined' // true

Refs属性无法传递

HoC中内定的 ref,并不会传递到子组件,供给经过回调函数使用 props 传递。

参考链接

高阶组件

上述正是本文的全体内容,希望对我们的上学抱有帮忙,也冀望我们多多协理帮客之家。

高阶组件入门介绍,react高阶组件入门
高阶组件的定义 HoC 不属于 React 的
API,它是壹种实现格局,本质上是七个函数,接受二个或两个…

Modal的布局

率先,让大家先研究下三个Modal组件的布局是怎么样的。

大家先拿三个主干的Modal样例来分析下。
澳门葡京 3

如上海教室所示,多个Modal组件可以分为mask、header、body和footer肆部分,mask就无须说了,header主倘诺呈现title和停业按键,body则是使用者自身传的内容,footer主固然开关控件。

零件设计

首先编写组件样式,然后遵照组件作用决定state结构

</br>
能够在作者的博客澳门葡京,http://haiyangjiajian.com/交换更多相关内容。

Modal组件的参数(props)

大家分明了Modal组件的布局之后,我们来想想一下Modal组件可援助传递的参数。

作为四个Modal组件,总要有标题(title)吧?要有用户自定义传入的剧情(children),还有一个规定按键文案(okText)和一个撤回开关文案(cancelText)吧,并且同意用户传入点击鲜明开关的回调函数(onOk)和点击撤废开关的回调函数(onCancel)。也急需有三个垄断Modal是还是不是出示的标记吗(visible)。所以,大意上有以下柒个变量。

澳门葡京 4

体制部分

依据陈设图可将零件分为如下几个部分

  1. app组件(即父组件)
    包蕴列表组件与右手显示与编写制定部分
  2. 列表组件
    CreateBar与列表项ListItem
  3. 来得组件与编辑组件

即一共6种组件


Modal的样式

首先,依照Modal组件的布局和参数,大家得以分明react
Modal的render函数如下:

澳门葡京 5

大家都晓得,Modal会覆盖在任何因素上边,并且首要分为两部分,壹部分为mask阴影部分,1部分为主旨内容,而且大旨部分会覆盖在阴影部分地点。让大家一步步来落实那几个效果。

  1. 实现mask效果

    .modal-mask {
      // 让mask铺满整屏
      position: fixed;
      top: 0;
      left: 0;
      right: 0;
      bottom: 0;
      background: black;
      opacity: 0.6;
      // 让mask覆盖在其他元素上面
      z-index: 1000;
    }
    
  2. 兑现重心内容的体制,让其覆盖在别的因素(包罗mask)上边,每1局地的服从能够看注释

    .modal-container {
      // 让Modal的主体内容全局居中,通过position: fix以及top和left的50%让主体内容的左上角居中,再通过transform:translate(-50%, -50%)来让主体内容正确居中。
      position: fixed;
      top: 50%;
      left: 50%;
      transform: translate(-50%, -50%);
    
      background: white;
      min-width: 500px;
      border-radius: 4px;
      // 设置主体内容的z-index高于mask的,从而可以覆盖mask
      z-index: 1001;
    }
    
  3. 接下去是body、footer和header样式的落到实处,这么些就径直贴代码了。

    .modal-title {
      padding: 30px;
      color: black;
      font-size: 20px;
      border-bottom: 1px solid #e8e8e8;
    }
    
    .modal-body {
      padding: 30px;
      font-size: 14px;
      border-bottom: 1px solid #e8e8e8;
    }
    
    .modal-footer {
      text-align: center;
      padding: 30px;
      display: flex;
    }
    
    .modal-footer .btn {
      flex: 1;
      height: 32px;
      text-align: center;
    }
    
    .modal-footer .modal-cancel-btn {
      background: white;
      margin-right: 30px;
      border-color: #d9d9d9;
      border-radius: 4px;
    }
    
    .modal-footer .modal-confirm-btn {
      background: #1890ff;
      color: white; 
    }
    

state数据结构

聊起state这里大致解说一下与props的区分

  • state
    各种组件都有协调的state,它是一个动态的,通过setState(data,callback)可将data与原state
    合并,使用该方式后组件会再一次render达到更新渲染组件的目标
  • props
    props仅为组件最初载入时传出的参数,载入后组件内容会根据state变化而再度render,此时state大概会作为props传入其他零件中程导弹致别的零件再度渲染。

接下去设计markdown中state数据结构,遵照最小组件state优化出最后state结构

  1. CreateBar
    该器件仅须要点击事件函数对象createItem
  2. ListItem
    该零件须要item中的title,time,selectItem函数对象
  3. 来得组件部分
    item的title,content,开关事件editItem与deleteItem
  4. 编纂组件部分
    item的title,content,开关事件saveItem与cancelItem

将享有state与事件函数统一放在app组件内,便于统一管理

澳门葡京 6

组件state

  • editing用于判定展现展示组件依旧编辑组件
  • selectedId用于事件之中操作items数组
  • items数组存款和储蓄全体日记记录

picker的效果

澳门葡京 7

![picker2.png]()

个中picker要来得的内容,百度、搜狗、谷歌(谷歌(Google))等均能够由父组件钦定,其样式也得以由父组件钦赐。

Modal的互动逻辑实现

实际Modal的并行是很轻易的,一般的调用方式如下:

澳门葡京 8

由外部传递自定义的body内容以及一些自定义的属性(比如title,点击按键的回调还有Modal的标题)

  1. 咱俩先定义Modal组件里的props

    澳门葡京 9

  2. 设置有些暗中认可的props,当用户未传入参数的时候,则运用暗中同意的props

    澳门葡京 10

  3. 落到实处render函数,依照用户传入的参数以及私下认可参数来渲染Modal节点,假若用户传入的visible属性为false(Modal不可知),则赶回null,不然,再次回到Modal节点。

    澳门葡京 11

那般,3个简易的react
Modal组件就达成了,上面包车型客车代码能够在
查看,并且能够一向看看3个demo例子。

意义图如下:

澳门葡京 12

末段再贴一下完全的Modal组件代码

// Modal.tsx
import * as React from 'react';
import './Modal.css';

interface IModalProps {
  children: React.ReactChild | React.ReactChildren |  React.ReactElement<any>[],
  title?: React.ReactChild,
  visible: boolean,
  onOk?: () => void,
  onCancel?: () => void,
  okText?: string,
  cancelText?: string,
} 

export default class Modal extends React.Component<IModalProps> {

  public static defaultProps = {
    cancelText: '取消',
    okText: '确定',
    visible: false,
  }

  public render() {
    const { title, visible, okText, cancelText, children, onOk, onCancel } = this.props;
    if (!visible)  {
      return null;
    };
    return (
      <div>
        <div className="modal-mask" onClick={onCancel}/>
        <div className="modal-container">
          <div className="modal-header">
            <div className="modal-title">{title}</div>
          </div>
          <div className="modal-body">
            {children}
          </div>
          <div className="modal-footer">
            <button className="modal-cancel-btn btn" onClick={onCancel}>{cancelText}</button>
            <button className="modal-confirm-btn btn" onClick={onOk}>{okText}</button>
          </div>
        </div>
      </div>
    )
  }
}

// Moda.css
.modal-mask {
  position: fixed;
  top: 0;
  left: 0;
  right: 0;
  bottom: 0;
  background: black;
  opacity: 0.6;
  z-index: 1000;
}

.modal-container {
  position: fixed;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
  background: white;
  min-width: 500px;
  border-radius: 4px;
  z-index: 1001;
}

.modal-title {
  padding: 30px;
  color: black;
  font-size: 20px;
  border-bottom: 1px solid #e8e8e8;
}

.modal-body {
  padding: 30px;
  font-size: 14px;
  border-bottom: 1px solid #e8e8e8;
}

.modal-footer {
  text-align: center;
  padding: 30px;
  display: flex;
}

.modal-footer .btn {
  flex: 1;
  height: 32px;
  text-align: center;
}

.modal-footer .modal-cancel-btn {
  background: white;
  margin-right: 30px;
  border-color: #d9d9d9;
  border-radius: 4px;
}

.modal-footer .modal-confirm-btn {
  background: #1890ff;
  color: white; 
}

组件交互

父组件一共有四个事件函数

  • selectItem(id)
    修改state中selectedId与editing的值
  • saveItem(item)
    成立新日记:在items中加多新item(需创立新的uuid与time)
    修改旧日记:在items中找与到item.id一样的记录并覆盖title与content
  • deleteItem(id)
    从items中删去对应id的item
  • createItem()
    当前selectedId设为null,editing设为true
  • editItem(id)
    修改item时还是呈现当前selectedItem同时editing改为编写制定状态
  • cancelItem()
    撤回编辑状态editing:false

组件封装

界面

本文封装了1个叫Picker的机件。1般推荐通过定义defaultProps来报告组件的调用者,能够流传这一个组件中的参数有哪些。能够见见能够流传的参数有style:组件样式;animationType:动画类型;transparent:是还是不是透明;modalVisible:是或不是可知;dataArray:展现的数目;title:标题。能够透过传播这几个参数,使那些组件具备不一样的体裁,展现不相同的数额。

static defaultProps = {
    style: View.propTypes.style,
    animationType: 'none',
    transparent: true,
    modalVisible: true,
    dataArray: [],
    title: 'title'
  };

  constructor(props) {
    super(props);

    this.state = {
      dataSource: this._getDataSource(props.dataArray),
      style: this.props.style,
      animationType: this.props.animationType,
      transparent: this.props.transparent,
      modalVisible: this.props.modalVisible,
    };
  }

组件内部的渲染代码如下,主体是三个Modal,然后是3个完完全全的view

<View style={[styles.modalContainer, {backgroundColor: 'rgba(0, 0, 0, 0.5)'}]}>

在那个view中最首要有两有的内容,一个是顶部的title,另三个是底层的listview,title显示从父组件中传出的标题,listview展现传入的dataArray。

<Modal
        animationType={this.state.animationType}
        transparent={this.state.transparent}
        visible={this.state.modalVisible}
        onRequestClose={() => {this._setModalVisible(false)}}>
        <View style={[styles.modalContainer, {backgroundColor: 'rgba(0, 0, 0, 0.5)'}]}>
          <View style={styles.viewContainer}>
            <View style={styles.titleRow}>
              <TouchableOpacity style={styles.cancelButton} onPress={() => {this._setModalVisible(false)}}>
                <Image style={styles.image}
                       source={require('../img/icon_cancel_grey.png')}/>
              </TouchableOpacity>
              <Text style={[styles.titleText, styles.modalTitle]}>{this.props.title}</Text>
            </View>
            <View style={[{marginTop: 0, marginBottom: 0}]}/>
            <ListView
              style={styles.flex}
              dataSource={this.state.dataSource}
              renderRow={(rowData, sectionID, rowID) => this._renderRow(rowData, sectionID, rowID)}
              renderScrollComponent={props => <RecyclerViewBackedScrollView {...props} />}
              renderSeparator={(sectionID, rowID) => <View key={`${sectionID}-${rowID}`} style={[GlobalStyles.divider, {marginTop: 0, marginBottom: 0, marginLeft: 16}]}/>}
            />
          </View>
        </View>
</Modal>

listView中每一个cell的渲染

 _renderRow(rowData, sectionID, rowID) {
    return (
      <TouchableHighlight onPress={() => this._pressRow(rowData, rowID)} underlayColor='gray'>
        <View>
          <View style={styles.row}>
            <Text style={styles.rowTitle}>
              {rowData.name}
            </Text>
          </View>
        </View>
      </TouchableHighlight>
    );
  }

上边是对这一个组件调用的贰个演示,puperseItems是二个格式化对象的数组,这几个指标涵盖了name,id,url多个属性

<Picker
            title="选择搜索引擎"
            dataArray={purposeItems}
            selectedData={(purpose) => {this.onPurposeSelected(purpose);}}
            onHideModal={() => this.setState({purposeModalVisible: false})}
/>

时至明日分界面包车型大巴显得完毕

操作

诸如此类二个组件首要有二种操作,点击当前列和关闭modal,如下多少个函数,主若是调用了父组件传递进入的selectedData和onHideModal回调

  _pressRow(rowData, rowID) {
    this.props.selectedData && this.props.selectedData(rowData);
    this.props.selectedIndex && this.props.selectedIndex(rowID);
  }

  _setModalVisible(visible) {
    this.setState({modalVisible: visible});
    if (visible) {
      this.props.onShowModal && this.props.onShowModal();
    } else {
      this.props.onHideModal && this.props.onHideModal();
    }
  }

迄今截至达成了3个组件的包装,可以灵活的显示父组件传入的数量,并拓展种种互动。

正文的言传身教源码能够在ReactNativeUIComponents下载

相关文章

发表评论

电子邮件地址不会被公开。 必填项已用*标注

*
*
Website