函數組件(Functional Component )和類組件(Class Component),劃分依據是根據組件的定義方式。函數組件使用函數定義組件,類組件使用ES6 class定義組件
// 函數組件 function Welcome(props) { return <h1>Hello, {props.name}</h1>; } // 類組件 class Welcome extends React.Component { render() { return <h1>Hello, {this.props.name}</h1>; } }
函數組件必定屬於無狀態組件 (劃分依據是根據組件內部是否維護state)
javascript
// 無狀態組件 class Welcome extends React.Component { render() { return <h1>Hello, {this.props.name}</h1>; } } // 有狀態類組件 class Welcome extends React.Component { constructor(props) { super(props); this.state = { show: true } } render() { const { show } = this.state; return ( <> { show && <h1>Hello, {this.props.name}</h1> } </> ) } }
展現型組件(Presentational Component)和容器型組件(Container Component),劃分依據是根據組件的職責。 (展現型組件通常是無狀態組件,不須要state)
class UserListContainer extends React.Component{ constructor(props){ super(props); this.state = { users: [] } } componentDidMount() { var that = this; fetch('/path/to/user-api').then(function(response) { response.json().then(function(data) { that.setState({users: data}) }); }); } render() { return ( <UserList users={this.state.users} /> ) } } function UserList(props) { return ( <div> <ul className="user-list"> {props.users.map(function(user) { return ( <li key={user.id}> <span>{user.name}</span> </li> ); })} </ul> </div> ) }
展現型組件和容器型組件是能夠互相嵌套的,展現型組件的子組件既能夠包含展現型組件,也能夠包含容器型組件,容器型組件也是如此。例如,當一個容器型組件承擔的數據管理工做過於複雜時,能夠在它的子組件中定義新的容器型組件,由新組件分擔數據的管理。展現型組件和容器型組件的劃分徹底取決於組件所作的事情。java
經過上面的介紹,能夠發現這三組概念有不少重疊部分。這三組概念都體現了關注點分離的思想:UI展示和數據邏輯的分離。函數組件、無狀態組件和展現型組件主要關注UI展示,類組件、有狀態組件和容器型組件主要關注數據邏輯。但因爲它們的劃分依據不一樣,它們並不是徹底等價的概念。它們之間的關聯關係能夠概括爲:函數組件必定是無狀態組件,展現型組件通常是無狀態組件;類組件既能夠是有狀態組件,又能夠是無狀態組件,容器型組件通常是有狀態組件。react
import React, { Component } from 'react' import { observer } from 'mobx-react' import { Switch } from 'antd' @observer class BaseInfoView extends Component { constructor(props) { super(props) } render() { const { ideaName, resourceLocationDto, switchState, slotId } = this.props.model return ( <div> <div className="adx-form-item-title">基本信息</div> <div className="ant-form-horizontal"> <div className="ant-form-item region"> <label className="ant-col-4 ant-form-item-label"> <span className="require-tip">*</span>創意名稱: </label> <div className="ant-col-19 ml10 region-input"> <div className="ant-form-text"> { ideaName } </div> </div> </div> <div className="ant-form-item region"> <label className="ant-col-4 ant-form-item-label"> <span className="require-tip">*</span>所屬資源位: </label> <div className="ant-col-19 ml10 region-input"> <div className="ant-form-text"> { resourceLocationDto && resourceLocationDto.resourceName } </div> </div> </div> <div className="ant-form-item region"> <label className="ant-col-4 ant-form-item-label"> <span className="require-tip">*</span>創意狀態: </label> <div className="ant-col-19 ml10 region-input"> <div className="ant-form-text"> <Switch checked={switchState == 1}/> </div> </div> </div> <div className="ant-form-item region"> <label className="ant-col-4 ant-form-item-label"> <span className="require-tip">*</span>推啊廣告位ID: </label> <div className="ant-col-19 ml10 region-input"> <div className="ant-form-text"> { slotId } </div> </div> </div> </div> </div> ) } } export default BaseInfoView
徹底能夠寫成函數組件json