React-redux提供Provider和connect两个接口链接
- Provider组件在应用最外层,传入store即可,只用一次
- Connect负责从外部获取组件需要的参数
- Connect可以用装饰器的方式来写
- 你要state什么属性放到props里
- 你要什么方法,放到props里,自动dispatch
- 两个reducers,每个reducers都有一个state
- 复杂redux应用,多个reducer,用combineReducers合并
- 合并所有reducer,并且返回
- 把store.dispatch方法传递给组件,内部可以调用修改状态
- connect负责链接组件,给到redux里的数据放到组件的属性里
1.负责接受一个组件,把state里的一些数据放进去,返回一个组件
2.数据变化的时候,能够通知组件
- Provider,把store放到context里,所有的子元素可以直接取到store
redux理论抽象,写一个例子:写一个需要登录的例子,有两个reducer。
0.gif
1.两个reducer:一个reducer用来控制登录态,一个用来管理机枪数量。通过combineReducers()合并到一个reducer中。
- authReducer:控制登录态,有登录和注销两个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:控制机枪数量,有增加机枪,减少机枪,过两天再加(异步)三个action。
const ADD_GUN = '加机关枪'
const REMOVE_GUN = '减机关枪'
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,可能根据业务需要会有多个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 () => {
//根据 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);
//调用 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方式调用。
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。
}
}
// // 发送行为
const mapDispatchToProps = ({
addGun: addGun,
removeGun: removeGun,
addGunAsync: addGunAsync,
login:login,
logout:logout
});
// const actionCreators = { addGun, removeGun, addGunAsync,login,logout}
// 进行第二层包装,生成的新组件拥有 接受和发送 数据的能力
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.点击申请武器则调用this.props.addGun,进入gunReducer响应对应key:ADD_GUN,默认state为10,state则加1。上交武器则调用this.props.removeGun,进入gunReducer响应对应key:REMOVE_GUN,state则减1,点击拖两天再给则调用this.props.this.props.addGunAsync,模拟异步延时两秒执行addGun(),两秒后state加1;点击登录,进入authReducer响应对应key:LOGIN,isAuth为true,点击注销,进入authReducer响应对应key:LOGOUT,isAuth为false。
_independentView() {
return (
<View>
<Text style={{
fontSize: 36,
textAlign: 'center',
margin: 10,
}}>
独立团
</Text>
<Text style={{ fontSize: 24 }}>
现在有机枪{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>你没有权限,需要登录才能看</Text>
<TouchableOpacity onPress={
this.props.login
}>
<Text style={{ fontSize: 24,alignSelf:'center',marginTop:36}}>登录</Text>
</TouchableOpacity>
</View>
)
}
Demo。
网友评论