一、如何创建React组件

方式一:React.createClass

用 React.createClass 构建组件是 React 最传统、也是兼容最好的方法。

const Button = React.createClass({
getDefaultProps() {
return {color: 'blue',text: 'http://jartto.wang'
};
},
render() {
const { color, text } = this.props;
return (
<button className={`btn btn-${color}`}>
<em>{text}</em>
</button>
);
}
});

React.createClass 方法就是构建一个组件对象。当另一个组件需要调用 Button 组件时,只用写成

<Button />

就可以被解析成 React.createElement(Button) 方法来创建 Button实例,这意味着在一个应用中调用几次 Button,就会创建几次 Button 实例。

方式二:ES6 classes

ES6 classes 的写法是通过 ES6 标准的类语法的方式来构建方法。

import React, { Component } from 'react';
class Button extends Component {
constructor(props) {
super(props);
}
static defaultProps = {color: 'blue',text: 'http://jartto.wang'
}
render() {
return (
<button className = { `btn btn-${color}`}>
<em>{text}</em>
</button>
)
}
}

与 createClass 的结果相同的是,调用类实现的组件会创建实例对象。在 React 组件开发中,常用的方式是将组件拆分到合理的粒度,用组合的方式合成业务组件。

React 的所有组件都继承自顶层类 React.Component,它的定义非常简洁,只是初始化了 ReactComponent 方法,声明了 props、context、refs 等,并在原型上定义了 setState 和 forceUpdate 方法。

内部初始化的生命周期方法与 createClass 方式使用的是同一个方法创建的。

方式三:无状态函数

使用无状态函数构建的组件称为无状态组件,这种构建方式是 0.14 版本之后增加的,且官方颇为推崇。

function Button({color='blue',text='http'){
return (
<button className = {`btn btn-${color}`}>
<em>{text}</em>
</button>
)
}

无状态组件只传入 props 和 context 两个参数。也就是说,它不存在 state,也没有生命周期方法,组件本身即上面两种 React 组件构建方法中的 render 方法。不过,像 propType 和 defaultProps 还是可以通过向方法设置静态属性来实现。

二、不同创建组件方式的使用场景

不错,我们有很多方式来创建 React 组件,那么问题来了,我们该如何抉择?这里我们把 React.createClass 和 ES6 classes 归为一类,称作有状态组件,而 function 类型的称为无状态组件。

下来我们主要来区分有状态组件和无状态组件的适用场景。

先来假设有这样的需求:在接入一个地图功能的时候,要求数据实时刷新,那么我们有两种方式实现:

其一:通过 sockets 来推数据,在初始化组件的时候,建立连接,然后动态更改数据;

其二:在组件初始化的时候,设置定时器更新数据,组件卸载时移除定时器;

当然,方式一需要后端 sockets 处理,我们用定时器来试试。那么问题其实已经转化为:如何在 React 组件中使用定时器,下面是官方推荐的写法:

class Timer extends React.Component {
constructor(props) {
super(props);
this.state = {secondsElapsed:0};
}
tick() {
this.setState((prevState)=>({secondsElapsed:prevState.secondsElapsed+1
}));
}
componentDidMount() {
this.interval=setInterval(()=>this.tick(),1000);
}
componentWillUnmount(){
clearInterval(this.interval);
}
render() {
return (
<div>Seconds Elapsed:
{this.state.secondsElapsed}
</div>
);
}
}
ReactDOM.render(<Timer />, mountNode);

计时器要 在componentDidMount 生命周期方法挂上,然后在 componentWillUnmount 生命周期方法清除。

无状态意味着也就没有生命周期函数,那么如果是这样的话,上述功能实现将不适合使用无状态组件方式,因为你很难找到合适的时机去创建和移除定时器。

无状态组件的创建形式使代码的可读性更好,并且减少了大量冗余的代码,精简至只有一个render方法,大大的增强了编写一个组件的便利,除此之外无状态组件还有以下几个显著的特点

(详情:http://www.cnblogs.com/wonyun/p/5930333.html)

组件不会被实例化,整体渲染性能得到提升

组件就不会在有组件实例化的过程,无实例化过程也就不需要分配多余的内存,从而性能得到一定的提升。

组件不能访问 this 对象

无状态组件由于没有实例化过程,所以无法访问组件this中的对象,例如:this.ref、this.state 等均不能访问。若想访问就不能使用这种形式来创建组件。

组件无法访问生命周期的方法

因为无状态组件是不需要组件生命周期管理和状态管理,所以底层实现这种形式的组件时是不会实现组件的生命周期方法。所以无状态组件是不能参与组件的各个生命周期管理的。

无状态组件只能访问输入的 props,同样的 props 会得到同样的渲染结果,不会有副作用。

从《深入 React 技术栈》中摘录到这样一句话:

在适合的情况下,我们都应该且必须使用无状态组件。无状态组件不像其他两种方法在调用时会创建新实例,它创建时始终保持了一个实例,避免了不必要的检查和内存分配,做到了内部优化。

三、组件生命周期

关于组件生命周期,我们先来看几个概念:

1.挂载与卸载过程;

组件的挂载是最基本的过程,这个过程主要做组件状态的初始化。下面是一个模板:

import React, { Component, PropTypes } from 'react';
class App extends Component {
// static 定义的 propTypes 和 defaultProps
// 可以在类外面访问,如:App.propTypes
static propTypes = { //props 类型检查 };static defaultProps = { //默认类型 };
constructor(props) {
super(props);
this.state = { //... };
}
componentWillMount()
{ // render 方法之前执行}
componentDidMount()
{ // render 方法之后执行}render()
{
return <div>jartto's blog</div>;
}
}
}
}
}
}
}

组件卸载非常简单,只有 componentWillUnmount 这一个卸载前状态:

import React, { Component, PropTypes } from 'react';
class App extends Component {
componentWillUnmount() { //... }render()
{
return <div>jartto's blog</div>;
}
}
}

在 componentWillUnmount 方法中,我们常常会执行一些清理方法,如事件回收或者是清除定时器。

2.生命周期;

componentWillMount 在渲染前调用,在客户端也在服务端。

componentDidMount 在第一次渲染后调用,只在客户端。之后组件已经生成了对应的DOM结构,可以通过this.getDOMNode()来进行访问。 如果你想和其他JavaScript框架一起使用,可以在这个方法中调用setTimeout, setInterval或者发送AJAX请求等操作(防止异部操作阻塞UI)。

componentWillUnmount在组件从 DOM 中移除的时候立刻被调用。

componentWillReceiveProps 在组件接收到一个新的prop时被调用。这个方法在初始化render时不会被调用。

shouldComponentUpdate 返回一个布尔值。在组件接收到新的props或者state时被调用。在初始化时或者使用forceUpdate时不被调用。

可以在你确认不需要更新组件时使用。

componentWillUpdate在组件接收到新的props或者state但还没有render时被调用。在初始化时不会被调用。

componentDidUpdate 在组件完成更新后立即调用。在初始化时不会被调用。

3.图示流程;

四、总结

React 中组件的使用不外乎文中写的这些,甚至在我们日常的项目中很多生命周期方法都用不到。但是作为一个开发者,我们要更深层次的理解这些,这样有助于我们使用最适当的方式去高效编程

微信号:migufe

Web前端Talk,你身边的前端助手,值得期待

react http请求_React组件的应用分析相关推荐

  1. react取消所有请求_react 组件关闭后怎么消除还在进行中的ajax

    把你的请求做成可以取消的, 这里的取消不是取消发送. 因为请求已经发送了,没有办法终止的. 所谓的取消其实就是取消回调函数, react官方给出了一种最佳实践.const makeCancelable ...

  2. react同步请求_React中setState同步更新策略

    setState 同步更新 我们在上文中提及,为了提高性能React将setState设置为批次更新,即是异步操作函数,并不能以顺序控制流的方式设置某些事件,我们也不能依赖于this.state来计算 ...

  3. 编写react组件_React组件的“黄金法则”如何帮助您编写更好的代码

    编写react组件 以及钩子如何发挥作用 (And how hooks come into play) Recently I've adopted a new philosophy that chan ...

  4. React实战开发-----一个有关兰州疫情分析的软件,本人负责前端开发,本博客记录整个开发的流程,供大家参考

    目录 前言 react介绍(觉得这些官方介绍啰嗦的直接看个人总结) 一.React的起源和发展 二.React的出发点 三.Recat与传统MVC的关系 四.React高性能的体现:虚拟DOM 五.R ...

  5. React 项目---class 创建组件 (11)

    回顾 function 创建组件 在前面的学习中,我们已经介绍了一种方法来创建组件 利用function,这里我们一起来回顾一下 function Hello(props){return <di ...

  6. react取消捕获_React 面试指南 (上)

    使用 React 进行项目开发也有好几个项目了,趁着最近有空来对 React 的知识做一个简单的复盘. 完整目录概览 React 是单向数据流还是双向数据流?它还有其他特点吗? setState Re ...

  7. react取消捕获_React学习笔记(三)

    React学习笔记(三),组件的生命周期 React中组件也有生命周期,也就是说也有很多钩子函数供我们使用, 组件的生命周期,我们会分为四个阶段,初始化.运行中.销毁.错误处理(16.3之后) 初始化 ...

  8. react 当前时间_React教程-State 生命周期

    通过调用 ReactDOM.render() 来修改我们想要渲染的元素: 在本文中,我们将学习如何封装真正可复用的 Clock 组件.它将设置自己的计时器并每秒更新一次. 我们可以从封装时钟的外观开始 ...

  9. 15、react 的 非受控组件 和 受控组件

    react 的 非受控组件 和 受控组件 组件分为 非受控组件 和 受控组件,这两种有什么区别呢,单说概念不好理解,那我们通过一个案例来说明一下,一下子就可以弄懂了,很简单的. 案例 还是,以案例的方 ...

最新文章

  1. 使用hibernate自动生成数据库表
  2. 关闭oracle自动统计,禁用oracle 11g 的统计数据自动功能
  3. python_循环删除list中的元素,有坑啊!
  4. 1、SpringBoot整合JPA
  5. depends用于测试程序运行所缺少的文件,可以帮我们很快找到问题
  6. jmeter一个线程组多个请求_分享一些我在实际项目中使用jmeter压测的一些技术点跟一些踩过的坑吧...
  7. java 不写this_还没弄明白Java中的this关键字吗,那来看这篇就够了!
  8. 线程安全list_多线程开发之如何创建一个线程安全的类
  9. 一个小问题(语法分析中的括号匹配)
  10. tcpip详解有必要看吗_全屋净水知识|前置过滤器有必要安装吗?看完秒懂
  11. 解决虎牙、斗鱼网页端P2P上传&增强虎牙、斗鱼网页端功能!
  12. 《G档案》中关于游戏程序设计的文章
  13. 自动化办公--通过BOM表输出原材料状态(第一版)
  14. 美团和滴滴,跨领域的竞争
  15. 【Mysql】1366 - Incorrect string value: ‘\xE9\x92\xB1\xE7\x94\xB5‘
  16. 苹果浏览器分辨率css,苹果(Safari)浏览器的图片width设置为100%但实际显示为980px改成的问题方法...
  17. Matlab 4. Matlab2016 不能保存数据(变量)的解决方法(中文版)-v7.3 switch
  18. 儿童学习桌有哪些升降方式
  19. Springboot就业推荐系统qwy6c计算机毕业设计-课程设计-期末作业-毕设程序代做
  20. excel单元格设置自动换行后导出显示不全原因

热门文章

  1. linux和redis笔记,Redis学习笔记一(Redis的详细安装及Linux环境变量配置和启动)...
  2. 值从哪里来_内存频率是怎么算出来的?2133MHz这么奇怪的数字是怎么来的?
  3. zookeeper watch java_Apache ZooKeeper Watcher 机制源码解释
  4. ptmalloc、tcmalloc与jemalloc内存分配器对比分析
  5. Docker在linux下的安装
  6. srsLTE源码学习:GTP:GPRS Turning Protocol- GPRS隧道协议
  7. ANSI C: union
  8. android webview权限申请_Android应用开发之android 6.0下webview的定位权限设置方法
  9. android studio下生成aar文件,本地调用
  10. 操作系统大作业模拟实现命令解释器_06 初识shell之系统命令基础