一. 引言
- 组件是近代工业发展的产物,兴起于20世纪初,目的是功能模块化,前提是接口标准化,好处是构成产品的各个功能组件,由更专业的厂商生产,提高了质量,降低了成本。而生产组件的厂商,同样的组件,可应用于多类产品和多个领域,极大地扩展了市场范围。
二. 什么是组件
- 概念:组件(Component)是对数据和方法的简单封装。
- 遵循5大准则:单一职责,开闭原则,里式替换,依赖反转,迪米特法则。
三. 组件的分类及应用
1. 无状态组件
- 无状态组件是最基础的组件形式,你可以简单理解为它就是一个无逻辑,只展示的组件。一般来说,各种UI库里也是最开始会开发的组件类别。如按钮、标签、输入框等。它的基本组成结构就是属性(props)加上一个渲染函数(render)。由于不涉及到状态的更新,所以这种组件的复用性也最强。
- 如:fuction组件
import React from "react"; function App(props) { return ( <div> { props.xxx } </div> ); } export default App;
2. 有状态组件
- 在无状态组件的基础上,如果组件内部包含状态(state)且状态随着事件或者外部的消息而发生改变的时候,这就构成了有状态组件(Stateful Component)。有状态组件通常会带有生命周期(lifecycle),用以在不同的时刻触发状态的更新。这种组件也是通常在写业务逻辑中最经常使用到的,根据不同的业务场景组件的状态数量以及生命周期机制也不尽相同。
import React, { Component } from "react"; export default class EventHandle extends Component { constructor(props) { super(props); this.state = { name: "" }; this.handleChange = this.handleChange.bind(this); } handleChange(e) { this.setState({ name: e.target.value }); } render() { return ( <div> <input type="text" value={this.state.name} onChange={this.handleChange} /> <p>{this.state.name}</p> </div> ); } }
3. 容器组件
- 容器组件就是存放一个通用数据和通用逻辑的数据仓库,它符合于设计模式的中介者模式。所有相关对象都可以通过数据仓库(中介者对象)进行通信。
- 举个例子:redux,vuex
- store/calculation.js
// action creator export const add = num => ({ type: "add", payload: num }); // action creator export const minus = num => ({ type: "minus", payload: num }); export const calculationReducer = (state = 0, action) => { const num = action.payload || 1; switch (action.type) { case "add": return state + num; case "minus": return state - num; default: return state; } };- store/index.js
import { calculationReducer } from './calculation' import logger from "redux-logger" import thunk from "redux-thunk" const store = createStore( calculationReducer, applyMiddleware(logger, thunk) ); export default store;- views/calculationNum.js
import { add, minus, asyncAdd } from "../store/calculation"; @connect( state => ({ num: state }), { add, minus, asyncAdd } ) class calculationNum extends Component { render() { return ( <div> {this.props.num} <div> <button onClick={ () => this.props.add(2) }>+</button> <button onClick={ this.props.minus }>-</button> </div> </div> ); } }
4. 高阶组件
- 高阶组件是一个工厂函数,它接收一个组件并返回另一个组件。返回的组件除了自己原有功能以外,还具有新的功能。
- 举个例子:A组件原来只有展示的功能,经过B组件的“赋能”之后,除了原有的展示以外,还可以打印出log,这时候就需要用到高阶组件了。
import React from "react"; // 无状态组件Lesson,不关心逻辑,只关心展示 function Lesson(props) { return ( <div> { props.stage } - { props.title } </div> ); } // 模拟数据 const lessons = [ { stage: "stage1", title: "title1" }, { stage: "stage2", title: "title2" }, { stage: "stage2", title: "title3" } ]; // 接收数据并进行展示 const withContent = Comp => props => { const content = lessons[props.idx]; return <Comp {...content} />; }; // 接收一个组件,保证组件在现有功能的基础上,打印出log const withLog = Comp => { return class extends React.Component { componentDidMount() { console.log('didMount', this.props); } render() { return <Comp {...this.props}></Comp> } } } // 装饰器语法 @withLog // 先后顺序:从下往上 @withLog @withContent class Lesson2 extends React.Component { render() { return ( <div> {this.props.stage} - {this.props.title} </div> ); } } export default function test() { return ( <div> {[0, 0, 0].map((item, idx) => ( <Lesson2 key={idx} idx={idx} /> ))} </div> ); }
四. 总结
- 以上这些是学习react组件的心得,如果可以掌握这些,对于日后项目组件代码的设计,解耦一定大有裨益。