【4858美高梅】react高阶组件入门,入手完毕react

By admin in 4858美高梅 on 2019年4月17日

Modal组件

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

咱俩先来看一下实际效果

花色概述

该品种为react演习demo,源代码点击那里,主要涉及内容

  1. 零件props与组件样式className
  2. 零件内传多少个子节点难点
  3. 通过ref使用真实dom
  4. state状态更动渲染组件
  5. props属性校验

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

4858美高梅 1

剧情呈现

点击编辑开关后,左侧展示组件会形成内容编排组件,那里能够须要贰个boolean类型值,遵照该值决定体现内容组件照旧编辑内容组件

4858美高梅 2

剧情编排

react
native在app开采上的四个优势正是组件化开采,当有了十足多的自定义组件后,能够很有益于的将这一个零部件拼装起来,开荒成效升高广大。本文少将以一个picker为例子,来讲如何包装2个通用性很强的react
native组件。本文的言传身教源码能够在ReactNativeUIComponents下载。这些项近期景会频频的护卫投入越来越多实用的零件,也力求那个类型得以用作2个react
native的言传身教项目,包罗了react native开辟中常用的router,navigator,code
push等,能够当做参照。

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

高阶组件的概念

HoC 不属于 React 的
API,它是一种达成方式,本质上是三个函数,接受3个或七个 React
组件作为参数,重回八个簇新的 React
组件,而不是改建现存的零件,这样的组件被叫做高阶组件。开垦进度中,有的职能须要在多少个零件类复用时,那时能够成立2个Hoc。

主干用法

卷入情势

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

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

在 WrappingComponent 中,能够读取、增加、编辑、删除传给
WrappendComponent 的 props,也足以用别的成分包裹
WrappendComponent,用来兑现封装样式、加多布局或其余操作。

组成情势

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()
调用父级的生命周期函数,不过这么会让七个零部件耦合在同步,下跌组件的复用性。

React
中对组件的包装是根据最小可用单元的思量来开始展览打包的,理想状态下,二个组件只做一件事情,符合
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属性无法传递

【4858美高梅】react高阶组件入门,入手完毕react。HoC中钦赐的 ref,并不会传送到子组件,供给通过回调函数使用 props 传递。

参考链接

高阶组件

如上正是本文的全部内容,希望对大家的就学抱有帮助,也希望我们多多协理帮客之家。

高阶组件入门介绍,react高阶组件入门
高阶组件的概念 HoC 不属于 React 的
API,它是1种达成情势,本质上是一个函数,接受三个或七个…

Modal的布局

首先,让大家先思量下一个Modal组件的布局是哪些的。

我们先拿叁个主导的Modal样例来分析下。
4858美高梅 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)。也急需有3个说了算Modal是还是不是出示的标识吧(visible)。所以,大要上有以下多少个变量。

4858美高梅 4

体制部分

基于规划图可将零件分为如下多少个部分

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

即一共6种组件


Modal的样式

率先,根据Modal组件的布局和参数,大家能够规定react
Modal的render函数如下:

4858美高梅 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)上面,每①局地的功用能够看注释

    .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. 4858美高梅,接下去是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,它是1个动态的,通过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与事件函数统1放在app组件内,便于统1保管

4858美高梅 6

组件state

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

picker的效果

4858美高梅 7

![picker2.png]()

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

Modal的竞相逻辑达成

实则Modal的相互是很轻便的,一般的调用格局如下:

4858美高梅 8

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

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

    4858美高梅 9

  2. 安装有个别暗中认可的props,当用户未传入参数的时候,则应用暗许的props

    4858美高梅 10

  3. 兑现render函数,遵照用户传入的参数以及默许参数来渲染Modal节点,假设用户传入的visible属性为false(Modal不可知),则赶回null,不然,重临Modal节点。

    4858美高梅 11

那般,1个大约的react
Modal组件就完事了,下边包车型地铁代码能够在
查看,并且可以一向看到二个demo例子。

作用图如下:

4858美高梅 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; 
}

零件交互

父组件1共有伍个事件函数

  • 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

零件封装

界面

正文封装了一个叫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,
    };
  }

组件内部的渲染代码如下,主体是2个Modal,然后是二个总体的view

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

在那个view中重视有两有个别剧情,1个是顶部的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>
    );
  }

上面是对这一个组件调用的2个演示,puperseItems是1个格式化对象的数组,那些指标涵盖了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();
    }
  }

时至后天达成了多个零部件的卷入,能够灵活的显示父组件传入的数据,并举行各类互动。

正文的演示源码能够在ReactNativeUIComponents下载

发表评论

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

网站地图xml地图
Copyright @ 2010-2019 美高梅手机版4858 版权所有