Skip to content
On this page

组件化开发

组件化思想的应用

  • 有了组件化的思想,我们在之后的开发中就要充分的利用它。
  • 尽可能的将页面拆分成一个个小的、可复用的组件。
  • 这样让我们的代码更加方便组织和管理,并且扩展性也更强。

组件分类:

  • 根据组件的定义方式,可以分为:函数组件 (Functional Component ) 和类组件 (Class Component);
  • 根据组件内部是否有状态需要维护,可以分成:无状态组件 (Stateless Component ) 和有状态组件 (Stateful Component);
  • 根据组件的不同职责,可以分成:展示型组件 (Presentational Component) 和容器型组件 (Container Component);
大体可以用一个公式表达
UI = F(state)
1
2
  • 以将 UI 切分成一些独立的、可复用的部件,这样你就只需专注于构建每一个单独的部件

  • 组件从概念上类似于 JavaScript 函数。它接受任意的入参(即 “props”),并返回用于描述页面展示内容的 React 元素

  • React 的组件相对于 Vue 更加的灵活和多样,按照不同的方式可以分成很多类组件:

    • 根据组件的定义方式,可以分为:函数组件 (Functional Component ) 和类组件 (Class Component);
    • 根据组件内部是否有状态需要维护,可以分成:无状态组件 (Stateless Component ) 和有状态组件 (Stateful Component);
    • 根据组件的不同职责,可以分成:展示型组件 (Presentational Component) 和容器型组件 (Container Component);

class 组件

类组件的定义有如下要求:

  • 组件的名称是大写字符开头(无论类组件还是函数组件)

  • 类组件需要继承自 React.Com-onent

  • 类组件必须实现 render 函数

  • 在 ES6 之前,可以通过 create-react-class 模块来定义类组件,但是目前官网建议我们使用 ES6 的 class 类定义。

  • 使用 class 定义一个组件:

    • constructor 是可选的,我们通常在 constructor 中初始化一些数据;
    • this.state 中维护的就是我们组件内部的数据;
    • render() 方法是 class 组件中唯一必须实现的方法;
jsx
import React , { Componet } from "react";

// 基于类的组件
export class Welcome2 extends Componet {
  constructor(props){
  	super(props);
    this.state = {
    	date: new Date()
    }
  }
  // 组件挂载完成之后执行
  componentDidMount(){
		this.timer = setInterval(()=>{
      // 更新state,不能调用this.state
    		this.setState({
        	date: new Date()
        })
    },1000)
	}
  componentWillUnmount(){
  	clearInterval(this.timer)
  }
  render() {
    return <div>{data.toLocaleTimeString()}</div>;
  }
}

class Welcome extends React.Component {
  render() {
    return <h1>Hello, {this.props.name}</h1>;
  }
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32

render 函数

  • 当 render 被调用时,它会检查 this.props 和 this.state 的变化并返回以下类型之一:
  • React 元素:
    • 通常通过 JSX 创建。
    • 例如,<div /> 会被 React 渲染为 DOM 节点,<MyComponent /> 会被 React 渲染为自定义组件;
    • 无论是 <div /> 还是 <MyComponent /> 均为 React 元素。
  • 数组或 fragments:使得 render 方法可以返回多个元素。
  • Portals:可以渲染子节点到不同的 DOM 子树中。
  • 字符串或数值类型:它们在 DOM 中会被渲染为文本节点
  • 布尔类型或 null:什么都不渲染。

函数组件

  • 函数组件是使用 function 来进行定义的函数,只是这个函数会返回和类组件中 render 函数返回一样的内容。
  • 函数组件有自己的特点(当然,后面我们会讲 hooks,就不一样了):
    • 没有生命周期,也会被更新并挂载,但是没有生命周期函数;
    • 没有 this(组件实例);
    • 没有内部状态(state);
    • 我们来定义一个函数组件
  • 函数组件接收一个单一的 props 对象并返回了一个 React 元素
jsx
import React, { useState, useEffect } from "react";

export function FunctionComponet(props) {
  const [date, setDate] = useState(new Date());
  useEffect(() => {
    // 相当于componentDidMounet,componetWillUnmount的集合
    const timer = setInterval(() => {
      setDate(new Date());
    }, 1000);
    return () => clearInterval(timer);
  }, []);
  return (
    <div>
      <h3>FunctionComponet</h3>
      <h3>{date.toLocaleTimeString()}</h3>
    </div>
  );
}

function Welcome(props) {
  return <h1>Hello, {props.name}</h1>;
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22

组件渲染

  • React 元素不但可以是 DOM 标签,还可以是用户自定义的组件
  • 当 React 元素为用户自定义组件时,它会将 JSX 所接收的属性(attributes)转换为单个对象传递给组件,这个对象被称之为 props
  • 组件名称必须以大写字母开头
  • 组件必须在使用的时候定义或引用它
  • 组件的返回值只能有一个根元素
jsx
function Welcome(props) {
  return <h1>Hello, {props.name}</h1>;
}
const element = <Welcome name="hello" />;

ReactDOM.render(
  element,
  document.getElementById('root')
);
1
2
3
4
5
6
7
8
9

React 只会更新必要的部分

  • React DOM 首先会比较元素内容先后的不同,而在渲染过程中只会更新改变了的部分。
  • 即便我们每秒都创建了一个描述整个 UI 树的新元素,React DOM 也只会更新渲染文本节点中发生变化的内容
沪ICP备20006251号-1