Redux組成
- state
存放redux屬性 - action
一個對象, 必須包含type屬性 - reducer
根據(jù)傳入的action更改state的值 - store
提供getState()方法獲取state
提供dispatch()方法發(fā)送action
通過subscribe()注冊監(jiān)聽
通過subscribe()的返回值注銷監(jiān)聽
react-redux
增加Provider和connect兩個重要部分
- Provider
被<Provider>包圍的所有組件中都可以獲取store中的數(shù)據(jù)
<Provider store={store}>
<App></App>
</Provider>
- connect
作用: 將組件和store關聯(lián)
Provider內部的組件如果想使用state中的數(shù)據(jù), 必須將組件用connect進行一層封裝
connect(p1,p2,...)(component組件)第一個括號返回一個函數(shù), 這個函數(shù)的入?yún)⑹且b的組件, 返回值是被connect增強的新的組件
connect入?yún)?
funciton mapStateToProps(state,ownProps) 作用:將store中的數(shù)據(jù)作為props綁定到組件上
state:redux中的store ownProps:自己的props
function mapDispatchToProps(dispatch,ownProps) 作用:將action作為props綁定到自己的函數(shù)中
dispatch: store.dispatch() ownProps: 自己的props
一個react-redux的基本流程
- 創(chuàng)建一個reducer
const reducer = (state=defaultState, action)=>{switch(action.type) .code.. return {...state}}
- 創(chuàng)建一個reducer
- 創(chuàng)建一個store對象
import {createStore} from 'redux'
const store = createStore(reducer)
- 創(chuàng)建一個store對象
- 將APP組件包裝進Provider, 并傳入store
import {Provider} from 'react-redux'
<Provider store={store}> <App/> </Provider>
- 將APP組件包裝進Provider, 并傳入store
- 使用connect加強組件
import {connect} from 'react-redux'
export default connect(mapStateToProps, mapDispatchToProps,...)(MyComponent)
- 使用connect加強組件
- 使用redux進行狀態(tài)管理的組件, 可以分為發(fā)送方和接收方. (也可以同時是兩者)
接收方: 實現(xiàn)mapStateToProps
發(fā)送方: 實現(xiàn)mapDispatchToProps
- 使用redux進行狀態(tài)管理的組件, 可以分為發(fā)送方和接收方. (也可以同時是兩者)
mapStateToProps
作為connect的第一個參數(shù)傳入, 作用是將store.state的指定屬性傳入組件的props中.
const mapStateToProps = (state)=>{
return {
myNumber:state.number
}
}
export default connect(mapStateToProps)(comB)
// 通過connect的加強, comB組件的props中多了一個myNumber的屬性
// 通過this.props.myNumber的調用, 可以訪問到store.state.number這個屬性
// 當store的reducer更改了state.number的時候, 組件中引用this.props.myNumber的UI也會刷新
-
mapDispatchToProps
作為connect的第二個參數(shù)傳入, 作用是將執(zhí)行store.dispath(action)的方法傳入組件的props中. 例如:
const mapDispatchToProps = (dispatch)=>{
return {
addClicked:()=>{
dispatch({
type:"action_add"
})
}
}
}
export default connect(null,mapDispatchToProps)(comA)
// 通過connect的加強, comA組件的props中多了一個addClicked的方法
// 通過this.props.addClicked()的調用, 會執(zhí)行store.dispatch(action)
// 執(zhí)行后會發(fā)送action, 從而是store的reducer執(zhí)行, 更新state, 進而更新UI
項目講解
[addButton] [100]
頁面效果如上, 按鈕部分定義為組件comA, 顯示數(shù)字的部分定義為組件comB. 頁面顯示在組件APP上.
工程組成:
-<store>
--index.jsx
-<reducer>
--index.jsx
-comA.jsx
-comB.jsx
-app.jsx
/*
reducer / index.jsx
*/
const defaultState = {
number:100
}
exports.reducer = (state=defaultState, action)=>{
console.log('reducer run',action.type);
switch (action.type) {
case 'action_add':
return {number:state.number+1}
default:
break;
}
return state;
}
/*
store / index.jsx
*/
import {createStore} from 'redux'
import {reducer} from '../reducer'
export default createStore(reducer)
/*
index.jsx
*/
import React from 'react'
import ReactDOM from 'react-dom'
import {Provider} from 'react-redux'
import ComA from './ComA'
import ComB from './ComB'
import store from './store';
class App extends React.Component{
render(){
return <Provider store={store}>
<ComA/>
<ComB/>
</Provider>
}
}
ReactDOM.render(<App />, document.getElementById('root'));
/*
store創(chuàng)建需要傳入reducer
將<APP>組件封裝到<Provider>中, 將store作為Provider的屬性傳入.
這樣整個<APP>組件及其子組件都可以訪問到store
*/
/*
comA.jsx
*/
import React from 'react'
import {connect} from 'react-redux'
class comA extends React.Component{
render(){
return <div>
<input type='button' value=' + ' onClick={this.add}></input>
</div>
}
add = ()=>{
console.log("button clicked",this.props)
this.props.addClicked()
}
}
// 發(fā)送方 需要實現(xiàn) connect 的第二個參數(shù) mapDispatchToProps
// 入?yún)⑹莻魅氲膕tore.dispatch
// 返回值是一個對象, 該對象的key是將要傳入的組件中的props的方法, value傳一個箭頭函數(shù), 函數(shù)中調用dispatch()
// dispatch()的入?yún)⑹且粋€action對象, action對象一定要有type屬性
// 該方法會將addClicked方法注入到組件的props中去, 組件中執(zhí)行this.props.addClicked(), 相當于執(zhí)行了store.dispatch(action)
// 每當store.dispatch(action)執(zhí)行時, store 而這個action的type就是action_add.
const mapDispatchToProps = (dispatch)=>{
return {
addClicked:()=>{
dispatch({
type:"action_add"
})
}
}
}
export default connect(null,mapDispatchToProps)(comA)
/*
comB.jsx
*/
import React from 'react'
import {connect} from 'react-redux'
class comB extends React.Component{
render(){
return <div>
<p>{this.props.myNumber}</p>
</div>
}
}
// 接收方 需要實現(xiàn)connect的第一個參數(shù) mapStateToProps
// 入?yún)⑹莝tore.state 返回值是一個對象, key是注入到組件的props中的屬性名, value可以從state中取
// 注入后可以再組件中的props中方為到state的屬性了
const mapStateToProps = (state)=>{
return {
myNumber:state.number
}
}
export default connect(mapStateToProps)(comB)