react系列知识---11组件间抽象
mixin
- mixin :將一個模塊混入到一個另一個模塊中,或是一個 類中
- 封裝 mixin 方法
- 在 React 中使用 mixin
React 在使用 createClass 構建組件時提供了 mixin 屬性,比如官方封裝的 PureRenderMixin :
import React from 'react'; import PureRenderMixin from 'react-addons-pure-render-mixin'; React.createClass({mixins: [PureRenderMixin],render() {return <div>foo</div>;} }); 復制代碼使用 createClass 實現的 mixin 為組件做了兩件事。
工具方法。這是 mixin 的基本功能,如果你想共享一些工具類方法,就可以定義它們,直 接在各個組件中使用。
生命周期繼承,props 與 state 合并。這是 mixin 特別重要的功能,它能夠合并生命周期方 法。如果有很多 mixin 來定義 componentDidMount 這個周期,那么 React 會非常智能地將它們都合并起來執行。同樣,mixin 也可以作用在 getInitialState 的結果上,作 state 的 合并,而 props 也是這樣合并的。
- ES6 Classes 與 decorator
decorator就是裝飾器:
- 在組件類里面的方法使用:在其上一行加@函數名(3個參數和Object.defineProperty一樣)
- 在組件類上使用:在其上一行加@類名(一個參數就是類實例)
參考1
參考2
- mixin 的問題
- 破壞了原有組件的封裝
- 命名沖突
- 增加復雜性 針對這些問題,React 社區提出了新的方式來取代 mixin,那就是高階組件
高階組件
- higher-order function(高階函數)在函數式 編程中是一個基本的概念,它描述的是這樣一種函數:這種函數接受函數作為輸入,或是輸出一 個函數。比如,常用的工具方法 map 、 reduce 和 sort 等都是高階函數
- 高階組件(higher-order component),類似于高階函數,它接受 React 組件作為輸入,輸出一 個新的 React 組件
高階組件讓我們的代碼更具有復用性、邏輯性與抽象特性。 它可以對 render 方法作劫持,也可以控制 props 與 state
實現高階組件的方法有如下兩種。
定義高階組件:
import React, {Component} from 'React'; const MyContainer = (WrappedComponent) => class extends Component {render() {return <WrappedComponent {...this.props}/>;} } 復制代碼使用高階組件:
import React, {Component} from 'React'; class MyComponent extends Component {// ... } export default MyContainer(MyComponent); 復制代碼用 decorator 來轉換:
import React, {Component} from 'React'; @MyContainer class MyComponent extends Component {render() {} } export default MyComponent; 復制代碼高階組件返回的組件繼承于 WrappedComponent。因為被動地繼承了 WrappedCom- ponent ,所有的調用都會反向,這也是這種方法的由來
組合式組件開發實踐
使用 React 開發組件時利用 props 傳遞參數。也就是說,用參數來配置 組件是我們最常用的封裝方式。在一般場景中,僅修改組件用于配置的 props,就可以滿足需求。 但隨著場景發生變化,組件的形態也發生變化時,我們就必須不斷增加 props 去應對變化,此時 便會導致 props 的泛濫,而在擴展過程中又必須保證組件向下兼容,只增不減,使組件的可維護 性降低
- 組件再分離
我們期望組件是沒有冗余的,組件與組件間視圖重疊的部分應當被抽離出來,形成顆 粒度更細小的原子組件,使組件組合充滿更多的可能
比如:抽離組件
對于顆粒度最小的組件而言,我們希望它是純粹的、木偶式的組件
對于 SelectInput 組件,其狀態完全依賴傳入的 props,包括 selectedItem (顯示用戶 所選項)、 isActive (當前下拉狀態)、 onClickHeader (反饋下拉狀態)以及 placeholder (下拉 框提示)。簡要實現:
class SelectInput extends Component {static displayName = 'SelectInput';render() {const {selectedItem, isActive, onClickHeader, placeholder} = this.props;const {text} = selectedItem;return (<div><div onClick={onClickHeader}><Input type="text" disabled value={text} placeholder={placeholder}/><Icon className={isActive} name="angle-down"/></div></div>);} } 復制代碼組件再次分離后,可以根據在現實中的組件形態對其進行任意組合,形成統一層,擺 脫在原有組件上擴展的模式,有效提高組件的靈活性
- 邏輯再抽象
組件層面的抽象不僅僅只停留在界面上,組件中的相同交互邏輯和業務邏輯也應該進行抽 象。在組件中,同樣貫穿著這種函數式思想,只是實現方式略有不同。現在基于高階組件來完成 組件邏輯上的抽象:
// 完成 SearchInput 與 List 的交互 const searchDecorator = WrappedComponent => {class SearchDecorator extends Component {constructor(props) {super(props);this.handleSearch = this.handleSearch.bind(this);}handleSearch(keyword) {this.setState({data: this.props.data, keyword});this.props.onSearch(keyword);}render() {const {data, keyword} = this.state;return (<WrappedComponent{...this.props}data={data}keyword={keyword}onSearch={this.handleSearch}/>);}}return SearchDecorator; } // 完成 List 數據請求 const asyncSelectDecorator = WrappedComponent => {class AsyncSelectDecorator extends Component {componentDidMount() {const {url, params} = this.props;fetch(url, {params}).then(data => {this.setState({data});});}render() {return (<WrappedComponent {...this.props} data={this.state.data}/>);}}return AsyncSelectDecorator; } 復制代碼最終,我們既可以用 decorator 的方式疊加套用,也可以利用 compose 方法將高階組件層層包 裹,將界面與邏輯完美地結合在一起:
const FinalSelector = compose(asyncSelectDecorator, searchDecorator, selectedItemDecorator)(Selector); class SearchSelect extends Component {render() {return (<FinalSelector {...this.props}><SelectInput/><SearchInput/><List/></FinalSelector>);} } 復制代碼在配置式組件內部,組件與組件間以及組件與業務間是緊密關聯的,而我們需要完成的僅僅 是配置工作
轉載于:https://juejin.im/post/5c26d071e51d4570f14553a9
總結
以上是生活随笔為你收集整理的react系列知识---11组件间抽象的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 关闭或启动linux防火墙后,docke
- 下一篇: 一位铁粉的分享:阿里面试归来总结面经,已