1. 程式人生 > >redux、react的連線

redux、react的連線

建議先了解:redux【博文:redux淺談】

例子:使用react與redux編寫一個計數器。

  • 使用react元件渲染頁面,兩個按鈕一個展示
  • 將計數器數值託管到redux中;提供+1和-1兩個action來更新狀態
  • 將redux中的state、發起action的方法通過屬性傳遞到元件中;並將state渲染為數值;將兩個方法註冊到按鈕的點選事件中
  • 渲染元件,並在state被更新時重新渲染。

一、redux與react手動連線

ReactDOM.render(
  <Counter
    value={Store.getState()}
    onIncrement={() => { store.dispatch({ type: "INCREMENT" }) }
    onDecrement={() => { store.dispatch({ type: "DECREMENT" }) }
  />,
  oRoot
)

缺點:

  • 無法給子元件傳遞state和方法
  • 任意state的變化,會導致整個狀態樹的重新渲染。

二、採用react-redux(推薦)

點評:可以給元件樹中任一元件繫結state和方法,還進行了效能優化,避免不必要的渲染。

步驟:

(1)首先安裝,

npm i react-redux -S

在所有元件的頂層,使用provider元件給整個程式提供store。

index.js

import { Provider } from "react-redux";

...

ReactDOM.render(
  <Provider store={store}>
  </Provider>
)

(2)共有多種寫法

第一種

connect()的第一個引數是一個函式,它將state.counter傳給元件counter屬性。

connect()的第二個引數是個物件,是所有action建立函式的集合。將所有的action建立函式傳到了元件的同名屬性。同時為每一個action建立函式隱式綁定了dispatch方法,因此可以在react元件內直接通過this.props呼叫這些action建立函式。

// container.js

import * as ActionCreators from "../actions";

export default connect(
  state => ({counter:state.counter}),
  ActionCreators
)(Counter)

第二種

connect()第二個引數是引數為dispatch的函式,該函式返回的物件也會被合併到組建的props中。備註:因為該方法不會為action建立函式繫結dispatch方法,所以需要手動繫結。

點評:有幾個action建立函式,在connect()裡就要分發多少次,麻煩~

container.js

export default connect(
  state => ({ counter: state.counter }),
  dispatch => ({
    increment: () => { dispatch(increment()) }
  })
)(Counter)

// increment為一個action建立函式

第三種

connect()第二個引數為dispatch函式,但是函式的返回值採用bindActionCreators來減少程式碼。

container.js

import * as ActionCreators from "../actions";
import { bindActionCreators } from "redux";

export default connect(
  state => ({ counter: state.counter }),
  dispatch => bindActionCreators(ActionsCreators, dispatch)
)(Counter)

第四種

在元件內發起action建構函式,進而connect()的第二個引數為空

點評:耦合度高,比較麻煩

container.js

function Counter({ counter, dispatch }) {
  return (
    <p>
      <button onClick={() => { dispatch(INCREMENT()) }}></button>
    </p>
  )
}

Counter.propTypes={
  counter:propTypes.number.isRequired,
}

export default connect(
  state => ({ counter: state.counter }),
)(Counter)

第五種

裝飾器寫法。將connect()寫在元件類宣告上面。注意:若採用裝飾器寫法,就不能使用無狀態函式來編寫元件。因為裝飾器新增在類宣告上面。

同時,必須使用static propTypes={}這種靜態屬性的寫法,來宣告props型別。

container.js

import * as ActionCreators from "../actions";

@connect(
  state=>({counter:state.counter}),
  ActionCreators
);

class Counter extends React.Component{
  static propTypes={
    counter:propTypes.number.isRequired,
  }

  render(){
    ....
  }
}

Ps:推薦書籍《react開發例項精解》臉譜書