redux相当于在vue技术栈中使用的vuex一样。那如何使用呢?
常见的搭配:
redux + react-redux + redux-thunk
或是 redux + react-redux + redux-saga
其他的mobox之类的,也有很多了。主流的就是这上面的两种。
本来,只有一个redux,其实就是可以使用了。
但是,为了在react技术中,使用的很爽,就加了一个react-redux,帮我们解决了redux中一些比较常用放繁琐的功能,就是加了几个api,让我们用redux比较顺手而已。
那为啥还要redux-thunk或redux-saga呢?
因为前面两个只解决了同步的问题。
我们业务中,肯定有网络请求这种异步操作啊,所有,引入redux-thunk或saga,目的是为了解决异步操作的。
yarn add redux react-redux redux-thunk
一个是actionsTypes.js
export const INCREASE = 'INCREASE';
export const DECREASE = 'DECREASE';
export const RESET = 'RESET';
一个是actions.js
import {INCREASE, DECREASE, RESET} from './actionsTypes';
// 同步action
const increase = () => ({type: INCREASE});
const decrease = () => ({type: DECREASE});
const reset = () => ({type: RESET});
// 异步action
const asyncincrease = () => {
return dispatch => {
setTimeout(() => {
dispatch(increase());
}, 2000);
};
};
export {increase, decrease, reset, asyncincrease};
总体来说,actions,是定义的操作名称。
reducers.js
import {combineReducers} from 'redux';
import {INCREASE, DECREASE, RESET, ASYNCINCREASE} from '../action/actionsTypes';
// 原始默认state
const defaultState = {
count: 5,
factor: 1,
};
function counter(state = defaultState, action) {
switch (action.type) {
case INCREASE:
return {...state, count: state.count + state.factor};
case DECREASE:
return {...state, count: state.count - state.factor};
case RESET:
return {...state, count: 0};
default:
return state;
}
}
export default combineReducers({
counter,
});
总体来说,dispach触发操作后,会在reducers中匹配名称,找到合适的type名称后,进行修改store。
store.js
import {createStore, applyMiddleware, compose} from 'redux';
import thunk from 'redux-thunk';
import rootReducer from './reducers/reducers';
const configureStore = preloadedState => {
return createStore(
rootReducer,
preloadedState,
compose(applyMiddleware(thunk)),
);
};
const store = configureStore();
export default store;
这里主要是实例化一个store,并且加入thunk中间件的操作。
搞完上面这个,最后在根组件中引入。
import React from 'react';
import {Provider} from 'react-redux';
import store from './redux/store';
import AppContainer from './Navigator';
export default class App extends React.Component {
constructor(props) {
super(props);
this.state = {};
}
render() {
return (
<Provider store={store}>
<AppContainer />
</Provider>
);
}
}
通过Provider,把store注入进去。
import React from 'react';
// 1.引入connect连接操作
import {connect} from 'react-redux';
// 2. 引入定义的actions操作。当然,也可以不用引入,直接传染源{ type:"RESET"}来操作。你记得的话。
import {
increase,
decrease,
reset,
asyncincrease,
} from '../../redux/action/actions';
import {
View,
Text,
StyleSheet,
TouchableOpacity,
} from 'react-native';
class Home extends React.Component {
constructor(props) {
super(props);
this.state = {
};
}
componentDidMount() {
}
componentWillUnmount() {
}
// 也可以定义成这种函数去触发调用哦! 当然,onPress内的操作,就需要改为onPress={()=>this._onPressReset()}这种形式来触发了。
// _onPressReset() {
// this.props.dispatch(reset());
// }
// _onPressInc() {
// this.props.dispatch(increase());
// }
// _onPressDec() {
// this.props.dispatch(decrease());
// }
// 5. 在视图层通过事件来触发修改操作
render() {
return (
<View>
<Text>我是文字</Text>
<Text>{this.props.counter.count}</Text>
<TouchableOpacity onPress={this.props._onPressReset}>
<Text>归零</Text>
</TouchableOpacity>
<TouchableOpacity onPress={this.props._onPressInc}>
<Text>加1</Text>
</TouchableOpacity>
<TouchableOpacity onPress={this.props._onPressDec}>
<Text>减1</Text>
</TouchableOpacity>
<TouchableOpacity onPress={this.props._onAsyncInc}>
<Text>2s后异步加1</Text>
</TouchableOpacity>
</View>
);
}
}
const styles = StyleSheet.create({
logo: {
width: 75,
height: 75,
alignSelf: 'center',
},
tabBarIcon: {
width: 21,
height: 21,
},
button: {
alignItems: 'center',
backgroundColor: 'green',
padding: 10,
},
});
// const mapStateToProps = state => ({
// counter: state.counter,
// });
// 3. 搞映射,定义操作
// 映射state 到 props
function mapStateToProps(state) {
return {
counter: state.counter,
};
}
// 映射 操作
function mapDispatchToProps(dispatch) {
return {
// 定义操作dispath触发action的操作函数
// _onPressReset: () => dispatch(reset()),
// 或者直接写{ type: 'xxxAction'} 这种操作。
_onPressReset: function() {
const action = {
type: 'RESET',
};
dispatch(action);
},
_onPressInc: () => dispatch(increase()),
_onPressDec: () => dispatch(decrease()),
_onAsyncInc: () => dispatch(asyncincrease()),
};
}
// 4.连接store和当前组件
export default connect(mapStateToProps, mapDispatchToProps)(Home);
总体来说,通过connect(mapStateToProps, mapDispatchToProps)(Home)
这个操作,把Home组件和store连接起来,并且,通过mapStateToProps把 store上面定义的state状态值映射为组件的props属性值,把dispath操作,映射为组件props属性值。大概是这个理解意思。
然后,在组件内,就可以通过this.props.counter.count
获取count这个store上的值,也可以通过dispatch
触发action操作,来修改store上的值,进而更新UI视图层。
附一个比较好的学习资料:
https://www.jianshu.com/p/21960f78937d
进阶学习资料
https://www.jianshu.com/p/d2615a7d725e