1、Component
React的首要思想是通过组件(Component)来开发应用。所谓组件,简单说,指的是能完成某个特功能的独立的、可重用的代码。
基于组件的应用开发是广泛使用的软件开发模式,用分而治之的方法把一个大的应用分解成若干小的组件,每个组件只关注于某个小范围的特定功能,但是把组件组合起来,就能够构成一个功能庞大的应用。如果分解功能的过程足够巧妙,那么每个组件可以在不同场景下重用,那样不光可以构建庞大的应用,还可以构建出灵活的应用。打个比方,每个组件是一块砖,而一个应用是一座楼,想要一次锻造就创建一座楼是不现实的。实际上,总是先锻造很多砖,通过排列组合这些砖,才能构建伟大的建筑。
任何一个复杂的应用,都是由一个简单的应用发展而来,当应用还很简单的时候,因为功能很少,可能只有一个组件就足够了,但是,随着功能的增加,把越来越多的功能放在一个组件中就会显得臃肿和难以管理。
就和一个人最好一次只专注做一件事情一样,也应该尽量保持一个组件只做一件事。当开发者发现一个组件功能太多代码量太大的时候,就要考虑拆分这个组件,用多个小的组件来代替。每个小的组件只关注实现单个功能,但是这些功能组合起来,也能满足复杂的实际需求。
这就是“分而治之”的策略,把问题分解为多个小问题,这样即容易解决也方便维护,虽然“分而治之”是一个好策略,但是不要滥用,只有必要的时候才去拆分组件,不然可能得不偿失。
拆分组件最关键的就是确定组件的边界,每个组件都应该是可以独立存在的,如果两个组件逻辑太紧密,无法清晰定义各自的责任,那也许这两个组件本身就不应该被拆开,作为同一个组件也许更合理。
虽然组件是应该独立存在的,但是并不是说组件就是孤岛一样的存在,不同组件之间总是会有通信交流,这样才可能合起来完成更大的功能。
作为软件设计的通则,组件的划分要满足高内聚和低耦合的原则。
高内聚指的是把逻辑紧密相关的内容放在一个组件中。用户界面无外乎内容、交互和样式。传统上,内容由HTML表示,交互行放在JavaScript代码文件中,样式放在CSS文件中定义。这虽然满足一个功能模块的需要,却要放在三个不同的文件中,这样其实不满足高内聚的原则。React却不是这样,展示内容的JSX、定义行为的JavaScript代码,甚至定义样式的CSS,都可以放在一个JavaScript文件中,因为它们本来就是为了一个目的而存在的,所以说React天生具有高内聚的特点。
低耦合指的是不同组件之间的依赖关系要尽量弱化,也就是每个组件要尽量独立。保持整个系统的低耦合度,需要对系统中的功能有充分的认识,然后根据功能点划分模块,让不同的组件去实现不同的功能。
2、类定义/函数定义组件
类定义组件:
使用ES6 class 来定义一个组件:
import React, { Component } from 'react';
class Title extends Component {
render() {
return <h1>Hello, {this.props.name}</h1>
}
}
或者你也可以这样写:
import React from 'react';
class Title extends React.Component {
render() {
return <h1>Hello, {this.props.name}</h1>
}
}
在代码的第一行,我们从react库中引入了React和Component,Component作为所有组件的基类,提供了很多组件共有的功能,class Title extends Component {}
,Title组件的父类就是Component。
仔细看上面的代码会发现我们导入的Component类在Title组件定义中被使用了,可是导入的React却没有被使用,试着删除第一行的React网页会立刻报错。
原因是在使用JSX的范围内必须有React。也就是说,在使用JSX的代码文件中,即使代码并没有直接使用React,也一定要导入这个React,这是因为JSX最终会被转译成依赖于React的表达式。
函数定义组件:
定义一个组件最简单的方式是使用JavaScript函数:
// 函数定义组件
function Title(props) {
return <h1>Hello, {props.name}</h1>
}
// 箭头函数语法
const Title = props => <h1>Hello, {props.name}</h1>
// 解构赋值语法
const Title = ({name}) => <h1>Hello, {name}</h1>
该函数是一个有效的React组件,它接收一个单一的“props”对象并返回了一个React元素。我们之所以称这种类型的组件为函数定义组件,是因为从字面上来看,它就是一个JavaScript函数。
补充:在React出现之初,使用的是React.createClass方式来创造组件类,这种方式已经被废弃了。
3、React组件的数据
React组件的数据分为两种,props和state,无论props或者state的改变,都可能已发组件的重新渲染。props是组件的对外接口,state是组件的内部状态,对外用props,内部用state。
React的props:
在React中,props是从外部传递给组件的数据,一个React组件通过定义自己能够接受的props就定义了自己的对外公共接口。
每个React组件都是独立存在的模块,组件之外的一切都是外部世界,外部世界就是通过props和组件对话的。
我们先从外部世界来看