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開發例項精解》臉譜書