React-redux提供Provider和connect兩個接口鏈接
- Provider組件在應(yīng)用最外層,傳入store即可,只用一次
- Connect負責從外部獲取組件需要的參數(shù)
- Connect可以用裝飾器的方式來寫
- 你要state什么屬性放到props里
- 你要什么方法拓萌,放到props里揍移,自動dispatch
- 兩個reducers,每個reducers都有一個state
- 復(fù)雜redux應(yīng)用绎秒,多個reducer,用combineReducers合并
- 合并所有reducer搔涝,并且返回
- 把store.dispatch方法傳遞給組件,內(nèi)部可以調(diào)用修改狀態(tài)
- connect負責鏈接組件曾雕,給到redux里的數(shù)據(jù)放到組件的屬性里
1.負責接受一個組件奴烙,把state里的一些數(shù)據(jù)放進去,返回一個組件
2.數(shù)據(jù)變化的時候剖张,能夠通知組件
- Provider,把store放到context里切诀,所有的子元素可以直接取到store
redux理論抽象,寫一個例子:寫一個需要登錄的例子修械,有兩個reducer趾牧。
0.gif
1.兩個reducer:一個reducer用來控制登錄態(tài)检盼,一個用來管理機槍數(shù)量肯污。通過combineReducers()合并到一個reducer中。
- authReducer:控制登錄態(tài),有登錄和注銷兩個action吨枉。
const LOGIN = 'LOGIN'
const LOGOUT = 'LOGOUT'
export function auth(state={isAuth:false,user:'李云龍'},action){
switch(action.type){
case LOGIN:
return {...state,isAuth:true}
case LOGOUT:
return {...state,isAuth:false}
default:
return state;
}
}
export function login(){
return {type:LOGIN}
}
export function logout(){
return {type:LOGOUT}
}
export default auth;
- gunReducer:控制機槍數(shù)量,有增加機槍蹦渣,減少機槍,過兩天再加(異步)三個action貌亭。
const ADD_GUN = '加機關(guān)槍'
const REMOVE_GUN = '減機關(guān)槍'
function counter (state=10,action){
switch(action.type){
case ADD_GUN:
return state + 1;
case REMOVE_GUN:
return state - 1;
default:
return 10;
}
}
export function addGun(){
return {type:ADD_GUN}
}
export function removeGun(){
return {type:REMOVE_GUN}
}
export function addGunAsync(){
return dispatch => {
setTimeout(
()=>{dispatch(addGun())
},2000)
}
}
export default counter;
- 合并兩個reducer:authReducer和gunReducer,可能根據(jù)業(yè)務(wù)需要會有多個reducer柬唯。
import counter from '../reducer/gunReducer';
import auth from '../reducer/authReducer';
import {combineReducers} from 'redux';
export default combineReducers({counter,auth});
2.reducer傳入store中,有異步會用到中間件。
import {createStore,applyMiddleware} from 'redux';
import thunk from 'redux-thunk';
import reducer from '../reducer/reducer'
export default () => {
//根據(jù) reducer 初始化 store
const store = createStore(reducer,applyMiddleware(thunk));
return store;
}
3.App中引入store,第一層包裝Provider圃庭。
import React, { Component } from 'react';
//引用外部文件
import {Provider} from 'react-redux';
import {createAppContainer,createStackNavigator} from 'react-navigation';
import Main from './app/containers/Main';
import LoginScreen from './app/containers/LoginScreen';
import contextScreen from './app/containers/ContextScreen';
import ContextToPropScreen from './app/containers/ContextToPropScreen';
import configureStore from './app/redux/store/store';
const store = configureStore();
let RootStack = createStackNavigator({
mainScreen:Main,
loginScreen:LoginScreen,
contextToPropScreen:ContextToPropScreen,
contextScreen:contextScreen
});
let Navigation = createAppContainer(RootStack);
//調(diào)用 store 文件中的 mainReducer常量中保存的方法
export default class App extends Component {
render() {
return (//第一層包裝锄奢,為了讓 main 能夠拿到 store
<Provider store={store}>
<Navigation />
</Provider>
)
};
}
4.引入reducer中的action失晴,在要用到redux中保存的action和state的頁面獲取state和action,鏈接器進行鏈接拘央。鏈接上之后state和action均以this.props.num,this.props.isAuth,this.props.login,this.props.logout方式調(diào)用涂屁。
import { connect } from 'react-redux';
import { addGun, removeGun, addGunAsync } from '../redux/reducer/gunReducer';
import {login,logout} from '../redux/reducer/authReducer'
// 獲取 state 變化
const mapStateToProps = (state) => {
return {
num: state.counter,//counter這個reducer中只有一個變量,可以直接賦值灰伟。
isAuth:state.auth.isAuth//redux中有兩個reducer,auth這個reducer中又包含兩個state:isAuth和user拆又。
}
}
// // 發(fā)送行為
const mapDispatchToProps = ({
addGun: addGun,
removeGun: removeGun,
addGunAsync: addGunAsync,
login:login,
logout:logout
});
// const actionCreators = { addGun, removeGun, addGunAsync,login,logout}
// 進行第二層包裝,生成的新組件擁有 接受和發(fā)送 數(shù)據(jù)的能力
Main = connect(mapStateToProps, mapDispatchToProps)(Main)
export default Main
5.render()里面判斷是否登錄,若登錄了栏账,跳到獨立團頁面帖族,未登錄跳登錄頁。
render() {
return(
<View style={{
flex: 1,
justifyContent: 'center',
alignItems: 'center',
backgroundColor: '#F5FCFF',
}}>
{this.props.isAuth ? this._independentView():this._loginView()}
</View>
);
}
6.點擊申請武器則調(diào)用this.props.addGun挡爵,進入gunReducer響應(yīng)對應(yīng)key:ADD_GUN,默認state為10竖般,state則加1。上交武器則調(diào)用this.props.removeGun,進入gunReducer響應(yīng)對應(yīng)key:REMOVE_GUN,state則減1,點擊拖兩天再給則調(diào)用this.props.this.props.addGunAsync,模擬異步延時兩秒執(zhí)行addGun(),兩秒后state加1;點擊登錄茶鹃,進入authReducer響應(yīng)對應(yīng)key:LOGIN,isAuth為true捻激,點擊注銷,進入authReducer響應(yīng)對應(yīng)key:LOGOUT,isAuth為false前计。
_independentView() {
return (
<View>
<Text style={{
fontSize: 36,
textAlign: 'center',
margin: 10,
}}>
獨立團
</Text>
<Text style={{ fontSize: 24 }}>
現(xiàn)在有機槍{this.props.num}把
</Text>
<TouchableOpacity style={{ marginTop: 36 }} onPress={this.props.addGun}>
<Text style={{ fontSize: 24,alignSelf:'center',marginTop:8}}>申請武器</Text>
</TouchableOpacity>
<TouchableOpacity onPress={this.props.removeGun}>
<Text style={{ fontSize: 24,alignSelf:'center',marginTop:8}}>上交武器</Text>
</TouchableOpacity>
<TouchableOpacity onPress={this.props.addGunAsync}>
<Text style={{ fontSize: 24,alignSelf:'center',marginTop:8 }}>拖兩天再給武器</Text>
</TouchableOpacity>
<TouchableOpacity style={{ marginTop: 36 }} onPress={this.props.logout}>
<Text style={{ fontSize: 24,alignSelf:'center' }}>注銷</Text>
</TouchableOpacity>
</View>
)
}
_loginView() {
return(
<View>
<Text>你沒有權(quán)限胞谭,需要登錄才能看</Text>
<TouchableOpacity onPress={
this.props.login
}>
<Text style={{ fontSize: 24,alignSelf:'center',marginTop:36}}>登錄</Text>
</TouchableOpacity>
</View>
)
}