這篇文章主要為大家介紹了關於React進階之組件的解耦之道,文中透過詳細的範例程式碼給大家介紹了組件分割與解耦的方法,對大家的學習或工作具有一定的參考學習價值,需要的朋友們下面跟著小編一起學習學習吧。
前言
眾所周知,React中的元件非常的靈活可擴展,不過隨著業務複雜度的增加和許多外部工具庫的引入,組件往往也會顯得浮腫,接下來我們就一起來看看常見的幾種,遵循單一職責原則的,組件分割與解耦的方法,話不多說了,來一起看看詳細的介紹:
一、分割render 函數
當一個元件渲染的內容較多時,有一個快速且通用的方法是建立sub-render函數來簡化原來龐大的render
class Panel extends React.Component { renderHeading() { // ... } renderBody() { // ... } render() { return ( <p> {this.renderHeading()} {this.renderBody()} </p> ); } }
為了再次簡化sub-render函數,我們也可以採用Functional Components寫法,這種方式生成了更小的處理單元,且更有利於測試
const PanelHeader = (props) => ( // ... ); const PanelBody = (props) => ( // ... ); class Panel extends React.Component { render() { return ( <p> // Nice and explicit about which props are used <PanelHeader title={this.props.title}/> <PanelBody content={this.props.content}/> </p> ); } }
#二、用props 傳遞元素
如果一個元件的狀態或配置較多,我們可以運用props傳遞元素而不僅是數據,例如再聲明一個元件,使其中的父元件只專注於配置
class CommentTemplate extends React.Component { static propTypes = { // Declare slots as type node metadata: PropTypes.node, actions: PropTypes.node, }; render() { return ( <p> <CommentHeading> <Avatar user={...}/> // Slot for metadata <span>{this.props.metadata}</span> </CommentHeading> <CommentBody/> <CommentFooter> <Timestamp time={...}/> // Slot for actions <span>{this.props.actions}</span> </CommentFooter> </p> ); } }
父元件
class Comment extends React.Component { render() { const metadata = this.props.publishTime ? <PublishTime time={this.props.publishTime} /> : <span>Saving...</span>; const actions = []; if (this.props.isSignedIn) { actions.push(<LikeAction />); actions.push(<ReplyAction />); } if (this.props.isAuthor) { actions.push(<DeleteAction />); } return <CommentTemplate metadata={metadata} actions={actions} />; } }
#三、使用高階元件
class Document extends React.Component { componentDidMount() { ReactDOM.findDOMNode(this).addEventListener('click', this.onClick); } componentWillUnmount() { ReactDOM.findDOMNode(this).removeEventListener('click', this.onClick); } onClick = (e) => { if (e.target.tagName === 'A') { // Naive check for <a> elements sendAnalytics('link clicked', { documentId: this.props.documentId // Specific information to be sent }); } }; render() { // ... } }
function withLinkAnalytics(mapPropsToData, WrappedComponent) { class LinkAnalyticsWrapper extends React.Component { componentDidMount() { ReactDOM.findDOMNode(this).addEventListener('click', this.onClick); } componentWillUnmount() { ReactDOM.findDOMNode(this).removeEventListener('click', this.onClick); } onClick = (e) => { if (e.target.tagName === 'A') { // Naive check for <a> elements const data = mapPropsToData ? mapPropsToData(this.props) : {}; sendAnalytics('link clicked', data); } }; render() { // Simply render the WrappedComponent with all props return <WrappedComponent {...this.props} />; } } return LinkAnalyticsWrapper; }
class Document extends React.Component { render() { // ... } } export default withLinkAnalytics((props) => ({ documentId: props.documentId }), Document);
以上是有關對React學習方法介紹的詳細內容。更多資訊請關注PHP中文網其他相關文章!