Loading [MathJax]/jax/output/CommonHTML/config.js
前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >小结React(二):组件知多少

小结React(二):组件知多少

原创
作者头像
前端林子
修改于 2019-04-20 11:33:09
修改于 2019-04-20 11:33:09
2.7K00
代码可运行
举报
文章被收录于专栏:前端技术总结前端技术总结
运行总次数:0
代码可运行

0.引入

React 16.8中正式发布了React Hooks,主要是想解决如何复用一个有状态的组件的问题。实际上React Hooks就是一系列特殊的函数,可以让本来无状态的函数组件变成有状态的,在组件内部hook组件的状态state和lifecycle。不过在正式总结React Hooks前,有必要搞清楚一些比较基本的问题,例如:什么是组件,什么是有状态组件和无状态组件,它们各自有什么特点,如何创建组件。本文根据这一思路将梳理关于React组件的基本内容,具体包括:

1.什么是组件

React的一个核心思想就是把页面拆分成一个个独立、可重用的组件,并且用自上而下的单向数据流将这些组件串联起来,在React中是这样定义组件的:

Components let you split the UI into independent, reusable pieces, and think about each piece in isolation.

就是说通过使用组件 可以把页面拆分为独立的、可重用的部分,并可以单独地考虑每个部分。

另外注意在React中组件名称必须以大写字母开头,React 会将以小写字母开头的组件视为原生 DOM 标签。例如,<div /> 代表 HTML 的 div 标签,而 <Welcome /> 则代表一个组件,并且需在作用域内使用 Welcome。

2.定义React组件的方式

React定义React组件的方式:

2.1函数组件

(1)出现版本:从React 0.14开始出现,可点击

(2)组件形式:函数组件是无状态的组件,只根据传入的属性props做展示、带有render方法。没有state状态的操作、没有生命周期lifecycle,可通过函数形式或者ES6的箭头函数创建。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
// 1,函数组件
function Welcome(props) {
    return <h1>Hello, {props.name}</h1>
}
ReactDOM.render(<Welcome name="Peter" />, document.getElementById('root'))

(3)函数组件的特点:

总的来说,React的建议是

This pattern is designed to encourage the creation of these simple components that should comprise large portions of your apps.

只要有可能,尽量使用无状态组件。

2.2类组件

提前说明:如果想创建一个类组件,请使用ES6的React.Component的形式来创建。

2.2.1ES5定义类组件的方式--React.createClass

(1)说明:这是React刚开始推荐的创建组件的方式。是ES5的原生的JavaScript来实现的React组件。再次强调,React更推荐用React.Component的方式去创建有状态的组件。

(2)组件形式:类组件是有状态的组件,自然组件要被实例化,且可以访问state、lifecycle。

示例:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
// 2,React.createClass
import React from 'react'
import ReactDOM from 'react-dom'
const SwitchButton = React.createClass({
    getDefaultProp: function () {
        return {
            open: false
        }
    },
    // 返回初始的state
    getInitialState: function () {
        return {
            open: this.props.open
        };
    },
    handleClick: function (event) {
        this.setState({
            open: !this.state.open
        });
    },
    render: function () {
        var open = this.state.open,
            className = open ? 'switch-button open' : 'switch-button';
        return (
            <label
                className={className}
                onClick={this.handleClick}>
                <input type="checkbox" checked={open} /></label>);
    }
});
ReactDOM.render(<SwitchButton />, document.getElementById('root'));

(3)React.createClass的特点:

2.2.2ES6定义类组件的方式--React.Component

(1)说明:是以ES6的方式来创建React组件

(2)组件形式

示例,上述代码用ES6的React.Component实现:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
// 3,React.Component
import React from 'react'
import ReactDOM from 'react-dom'
class SwitchButton extends React.Component {
    constructor(props) {
        super(props)
        // 返回初始的state,相当于ES5中的getInitailState
        this.state = {
            open: this.props.open
        }
        // 这句要注意,React.component中函数不会自动绑定this,要手动绑定
        this.handleClick = this.handleClick.bind(this)
    }
    handleClick(event) {
        this.setState({
            open: !this.state.open
        })
    }
    render() {
        let open = this.state.open, className = open ? 'switch-button open' : 'switch-btn'
        return (
            <label
                className={className}
                onClick={this.handleClick}>
                <input type="checkbox" checked={open} /></label>)
    }
}
// 相当于React.createClass中的getDefaultProps
SwitchButton.defaultProps = {
    open: false
}
ReactDOM.render(<SwitchButton />, document.getElementById('root'))

需要注意,React.component中函数不会自动绑定this,要手动绑定。有三种手动绑定的方式:

-- 在构造函数中绑定,就是上述示例中采用的方法:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
constructor(props) {
    super(props)
    this.state = {
        ...
    }
    this.handleClick = this.handleClick.bind(this)
}

-- 在调用时绑定:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
onClick={this.handleClick.bind(this)}

-- 使用ES6的箭头函数来绑定:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
onClick={()=>this.handleClick()}

(3)React.Component的特点:

2.2.3React.createClass和React.Component如何选择?

The most notable new feature is support for ES6 classes , which allows developers to have more flexibility when writing components. Our eventual goal is for ES6 classes to replace React.createClass completely, but until we have a replacement for current mixin use cases and support for class property initializers in the language, we don’t plan to deprecate React.createClass.

可以看出React更推荐以React.Component的形式来创建一个有状态的组件,React.Component最终会完全取代React.createClass。但在找到Mixins的替代方案前,不会废弃掉React.createClass。不过9102年了,在HOC、Render Props、React Hooks这些解决方案都出现的今天,Mixins已被开发团队坚决地舍弃了。总的来说,现在要创建一个有状态的组件,请用React.Component的形式来创建。

2.2.4 函数组件和React.Component如何选择

1,尽可能使用函数组件创建;

2,除非需要state、lifecycle等,使用React.Component这种ES6的形式创建有状态的类组件;

3,如果想在函数组件中使用state、lifecycle,使用React Hooks;

3.有状态组件和无状态组件

上面已经说过,函数组件是无状态的组件,类组件是有状态的组件。

React中有五类API

  • render
  • state
  • props
  • context
  • lifecycle events

有状态的组件:组件内部可以使用状态(state)、生命周期(lifecycle)、render

无状态的组件:组件内部可以使用属性(props)、context、render。

更多关于React组件模式的内容,可以阅读 React组件模式

4.受控组件和非受控组件

所谓受控组件、非受控组件,都是针对form表单而言的。

4.1受控组件

受控组件就是表单元素有当前值(value),同时还有一个回调函数(onChange)可以改变这个值,回调函数中通过使用setState()更新对应的state值,示例:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
// 受控组件
import React from 'react'
class Form extends React.Component {
    constructor(props) {
        super(props);
        this.state = {
            name: '',
        };
    }

    handleNameChange = (event) => {
        // 在回调函数中用event.target.value获取新的值
        this.setState({
            name: event.target.value
        });
    };

    render() {
        return (
            <div>
                <input
                    type="text"
                    value={this.state.name}
                    onChange={this.handleNameChange}
                />
            </div>
        );
    }
}

4.2非受控组件

非受控组件是不受状态的控制,可以使用defaultValue、defaultChecked设置初始值,使用ref来获取DOM的值。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
<input
    type="text" 
    defualtValue="Peter" 
    ref={input => this._name = input} 
/>

形式上,如果是通过value属性、checked属性来设置表单元素的值,那么表单元素就是受控的。如图,右边是受控的:

5.小结

万丈高楼平地起,作为介绍React Hooks的基础篇,本文主要梳理了什么是组件、三种创建组件的方式,各自的特点,以及如何进行选择。接下来总结了什么是有状态组件、无状态组件、受控组件和非受控组件。如有问题,欢迎指正。

6.参考文章:

[1]http://www.cnblogs.com/wonyun/p/5930333.html

[2]https://medium.com/teamsubchannel/react-component-patterns-e7fb75be7bb0

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

评论
登录后参与评论
暂无评论
推荐阅读
编辑精选文章
换一批
React的无状态和有状态组件
众所周知,React是一个专注于View层的前端框架,组件也】是React核心理念之一,一个完整的应用将由一个个独立的组件拼装而成,组件也是React最基础的一部分,学习React就需要先学习组件。
xiangzhihong
2022/11/30
1.7K0
React创建组件的三种方式及其区别
虽然有三种方式可以定义react的组件,那么这三种定义组件方式有什么不同呢?或者说为什么会出现对应的定义方式呢?下面就简单介绍一下。
前朝楚水
2018/07/26
2K0
React Object实现React对象
如果不使用ES6语法,可以直接使用 React.createClass 来实现相同的功能:
随风溜达的向日葵
2018/08/07
8710
一天梳理完react面试题
setState 是 React 中最常用的命令,通常情况下,执行 setState 会触发 render。但是这里有个点值得关注,执行 setState 的时候不一定会重新渲染。当 setState 传入 null 时,并不会触发 render。
beifeng1996
2022/11/14
5.6K0
(转) 谈一谈创建React Component的几种方式
原文地址:http://www.cnblogs.com/Unknw/p/6431375.html
mafeifan
2018/09/10
5260
小结React(一):组件的生命周期及执行顺序
本文作为React总结系列的第一篇文章,会总结组件的生命周期及执行顺序,涉及内容比较基础。在后面的系列文章中则会总结React Hooks等内容。
前端林子
2019/04/13
4.9K0
小结React(一):组件的生命周期及执行顺序
React组件基础
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-5zo7zriO-1668351209724)(images/组件.png)]
用户10169043
2022/11/18
3.2K0
React组件基础
React组件详解
众所周知,组件作为React的核心内容,是View的重要组成部分,每一个View页面都由一个或多个组件构成,可以说组件是React应用程序的基石。在React的组件构成中,按照状态来分可以分为有状态组件和无状态组件。 所谓无状态组件,就是没有状态控制的组件,只做纯静态展示的作用,无状态组件是最基本的组件形式,它由属性props和渲染函数render构成。由于不涉及到状态的更新,所以这种组件的复用性也最强。 有状态组件是在无状态组件的基础上增加了组件内部状态管理,有状态组件通常会带有生命周期lifecycle,用以在不同的时刻触发状态的更新,有状态组件被大量用在业务逻辑开发中。
xiangzhihong
2022/11/30
1.7K0
React学习(2)——状态、事件与动态渲染 原
    上一篇文章最后说明了组件传入的参数必须是只读的,但是在丰富的前端应用中,页面样式是时时刻刻会发生变化的。在前面的章节中介绍了一个时钟的例子,通过重复调用ReactDOM.render() 来渲染组件:
随风溜达的向日葵
2018/08/15
3K0
【React】组件&事件
在components文件夹下,创建函数组件hello.js,类组件home.js,
且陶陶
2023/04/12
1K0
【React】组件&事件
面试官:你是怎样进行react组件代码复用的
Mixin(混入)是一种通过扩展收集功能的方式,它本质上是将一个对象的属性拷贝到另一个对象上面去,可以拷贝多个属性到一个对象上,为了解决代码复用问题。
beifeng1996
2022/10/11
3860
React 基础实例教程
首先,需要核心库react.js与React的DOM操作组件react-dom.js
书童小二
2018/09/03
4.4K0
React  基础实例教程
React 开发要知道的 34 个技巧
原理:子组件里面利用 props 获取父组件方法直接调用,从而改变父组件的值 注意: 此方法和 props 大同小异,都是 props 的应用,所以在源码中没有举例
前端老王
2020/09/23
1.5K0
年前端react面试打怪升级之路
总结: 类组件可以维护自身的状态变量,即组件的 state ,类组件还有不同的生命周期方法,可以让开发者能够在组件的不同阶段(挂载、更新、卸载),对组件做更多的控制。类组件则既可以充当无状态组件,也可以充当有状态组件。当一个类组件不需要管理自身状态时,也可称为无状态组件。
beifeng1996
2022/11/04
2.4K0
React 开发必须知道的 34 个技巧【近1W字】
React 是前端三大框架之一,在面试和开发中也是一项技能; 本文从实际开发中总结了 React 开发的一些技巧技巧,适合 React 初学或者有一定项目经验的同学; 万字长文,建议收藏。 序列文章:Vue 开发必须知道的 36 个技巧【近1W字】
火狼1
2019/11/13
3.6K0
20道高频react面试题(附答案)
在调用 super() 方法之前,子类构造函数无法使用this引用,ES6 子类也是如此。
beifeng1996
2022/09/16
1.4K0
React组件方法中为什么要绑定this
上例仅仅是一个组件类的定义,当在其他组件中调用或是使用ReactDOM.render( )方法将其渲染到界面上时会生成一个组件的实例,因为组件是可以复用的,面向对象的编程方式非常适合它的定位。根据this指向的基本规则就可以知道,这里的this最终会指向组件的实例。
大史不说话
2019/03/01
9530
前端必会react面试题合集2
(2)如果已经创建了 Create React App 项目,需要将 typescript 引入到已有项目中
beifeng1996
2023/01/04
2.4K0
React.js 实战之深入理解组件sublime 插件安装组件间通信
sublime 插件安装 用Package Control安装 按下Ctrl+Shift+P调出命令面板 输入install 调出 Install Package 选项并回车,然后在列表中选中要安
JavaEdge
2018/06/06
1.1K0
react新手教程
github仓库 https://github.com/Rynxiao/react-newer JSX语法 const element = <h1>Hello, world!</h1>; This funny tag syntax is neither a string nor HTML. It is called JSX, and it is a syntax extension to JavaScript. We recommend using it with React to describe w
糊糊糊糊糊了
2018/05/09
2.1K0
相关推荐
React的无状态和有状态组件
更多 >
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档
本文部分代码块支持一键运行,欢迎体验
本文部分代码块支持一键运行,欢迎体验