1. 程式人生 > >React的組件模式

React的組件模式

tdi 通過 nec 回調函數 函數類 簡單 port 如何 組織

組件化開發是React的核心,學會如何利用和組織他們有助於你創建良好的設計結構。

什麽是組件?

根據react官網的解釋大致如下:

組件可以獨立的拆分你的UI試圖,他們是可以復用的,獨立的單元。

和函數類似,React中組件接收的輸入源稱為props,並且返回react元素。react元素是對UI界面的描述。你可以告訴react你期望的UI界面,剩下的工作可以交給react來處理。

我們拿乘坐計程車打比方,當你告訴司機你想要去的地方,司機就會按照你期望地點將你安全的送到目的地。而不用你自己親自開車。

Component Api‘s

react的api有哪些呢?react總共有主要的5大api他們分別是:

1.render

2.state

3.props

4.context

5.life cycle events

組件有狀態組件和無狀態組件,狀態組件使用可控制狀態的api,render state 和life cycle events。無狀態組件使用render props context。

組件設計模式,可以將你的數據層和邏輯層分開,通過職責區分你的組件。你可以創建可以復用的組件,而這些組件又可以創建出更加復雜的UI試圖。這對於構建app是極為重要的。

在組件設計模式中我們可以將組件分為:

1.容器組件

2.展示型組件

3.高階組件

4.render回調

容器組件:

容器組件用於獲取數據,渲染他下面的子組件,這個就是容器組件。

容器組件可以是你的數據層或者業務邏輯層,並且使用的是stateful api。通過生命周期函數你可以連接你的狀態管理庫,例如redux或者flux。容器組件可以傳遞數據和回調函數給子組件。在容器組件的render方法中,通過展示組件的組合來構建你的UI試圖。因為容器組件是具有狀態的,所以你需要使用class來聲明你的組件,而不是使用函數式組件。

在如下例子中,有個class component名為Greeting,他有state,生命周期函數和render函數。

class Greeting extends React.Component {
  constructor() {
    super();
    
this.state = { name: "", }; } componentDidMount() { // AJAX this.setState(() => { return { name: "William", }; }); } render() { return ( <div> <h1>Hello! {this.state.name}</h1> </div> ); } }

這個組件是具備狀態的class組件。為了讓Greeting組件成為容器型組件,我們需要把UI拆分到展示型組件中。如下:

展示型組件:

展示型組件利用的是,props,render,context(stateless api‘s)

const GreetingCard = (props) => {
  return (
    <div>
      <h1>Hello! {props.name}</h1>
    </div>
  )
}

容器組件通過props傳遞數據和回調函數給展示型組件。通過容器組件和展示型組件來共同封裝業務邏輯,並組合成新的組件。

const GreetingCard = (props) => {
  return (
    <div>
      <h1>{props.name}</h1>
    </div>
  )
}

class Greeting extends React.Component {
  constructor() {
    super();
    this.state = {
      name: "",
    };
  }

  componentDidMount() {
    // AJAX
    this.setState(() => {
      return {
        name: "William",
      };
    });
  }

  render() {
    return (
      <div>
       <GreetingCard name={this.state.name} />
      </div>
    );
  }
}

如上示例,我們移除了標簽元素,並且將他放入了無狀態的展示型組件中。當然這個只是這個很簡單的示例,但是在復雜的app運用中,原理都是相同的。

高階組件:

高階組件,是以組件作為參數,並且返回一個新的組件。

高階組件可以提供數據給任意數量的組件,並且有效的復用業務邏輯。它是個強大的模式。例如在react-router和redux中,在react-router中你可以使用widthRouter()去繼承方法,並且通過props傳遞給你的組件。在redux中你可以connect方法去傳遞你的actions。

import {withRouter} from ‘react-router-dom‘;

class App extends React.Component {
  constructor() {
    super();
    this.state = {path: ‘‘}
  }
  
  componentDidMount() {
    let pathName = this.props.location.pathname;
    this.setState(() => {
      return {
        path: pathName,
      }
    })
  }
  
  render() {
    return (
      <div>
        <h1>Hi! I‘m being rendered at: {this.state.path}</h1>
      </div>
    )
  }
}

export default withRouter(App);

如上示例,我們通過this.props.location.pathname來更新狀態。通過withRouter方法來包裹組件。現在我們的組件可以通過props來出來react-rouoter的方法this.props.location.pathname;

Render callbacks

類似於高階組件,render callbacks或者render props都是用來復用組價邏輯的。當更多的開發者傾向於高階組件來復用業務邏輯的時候,這裏有幾個原因和優點可以讓你嘗試下使用render callbacks。render callsbacks可以有效的減少命名沖突,並且清晰的展示邏輯的來源。

class Counter extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      count: 0,
    };
  }

  increment = () => {
    this.setState(prevState => {
      return {
        count: prevState.count + 1,
      };
    });
  };

  render() {
    return (
      <div onClick={this.increment}>{this.props.children(this.state)}</div>
    );
  }
}

class App extends React.Component {
  render() {
    return (
      <Counter>
        {state => (
          <div>
            <h1>The count is: {state.count}</h1>
          </div>
        )}
      </Counter>
    );
  }
}

在Counter類的render方法中,內嵌了this.props.children並且以this.state作為參數傳入。再App類中我們可以再Counter中包裹我們的組件來處理Counter的邏輯。因此他可以處理來自Counter中的state。

React的組件模式