- 本猪说
本猪猪刚学react,也刚看RN,就叫写这个,苦不堪言,搭环境就搭了好久。看网上教程也是改了好多小地方才写完了。本着雷锋精神手把手教你写(假的)。
- 环境以及版本
我用的是安卓模拟器跑的,不过应该ios也适配吧。
这是我的demo的配置依赖的版本
- 项目结构
红色的框框是需要我们自己建立的,因为这个demo的action比较简单,老师叫我把它写在Login.js里面了,所以没有写在action文件里。
- 登录视图 screens/Login.js
import React, {Component} from 'react';
import { StyleSheet,Text, TextInput, View, Image, TouchableOpacity, Dimensions,Alert} from 'react-native';
import {connect} from 'react-redux';
var {height, width} = Dimensions.get('window');
class Login extends Component {
constructor(props) {
super(props);
}
----------
onSubmit(userName,password){
if(userName===''||password===''){
Alert.alert('登陆失败!用户名或密码不能为空'); //弹出提示框
} else{
// 成功
Alert.alert('user: '+userName+' password:'+password);
}
}
// onSubmit()是点击登录按钮后调用的函数,这里的功能比较简单。这里输入不为空都可以,之后的逻辑后面的事了,先让我们取到输入值就ok了
----------
render() {
----------
const {userName,password,dispatch} = this.props;
//这个是es6的赋值语法。
这里可以获取到dispath,是因为我们在下面会用到**connect**封装。
当你用React Redux的connect进行封装的时候,connect方法会把dispatch放到props中
----------
return (
<View style={styles.wrapper}>
<Image
style={{width: 90, height: 90, margin:30, borderRadius:50}}
source={{uri:'这里放你可爱的头像'}}
/>
<TextInput style={styles.textInput} placeholder="请输入用户名"
**onChangeText={(userName)=>{dispatch({type: 'LOGINUSER', userName:userName})}}**
/>
----------
组件发出请求,也就是action。通过dispatch把action发出去
----------
<TextInput style={styles.textInput} placeholder="密码" secureTextEntry={true}
**onChangeText={(password)=>{dispatch({type: 'LOGINPASS', password:password})}}**/>
<TouchableOpacity style={styles.button} activeOpacity={0.6} **onPress={this.onSubmit.bind(this,userName,password)}**>
<Text style={styles.buttonText}>登录</Text>
</TouchableOpacity>
</View>
)
}
}
const styles = StyleSheet.create({
wrapper:{
paddingTop:40,
flex:1,
alignItems:'center',
// backgroundColor:'#444',
backgroundColor:'#e7cbcb'
},
textInput:{
backgroundColor:'#eee',
borderColor: 'gray',
borderWidth: 2,
width:width,
height:60,
marginBottom:10,
textAlign:'center',
fontSize:18
},
button: {
backgroundColor: '#808182',
// backgroundColor: '#64d0ee',
height:60,
width:width
},
buttonText: {
color:'#fff',
height:60,
lineHeight:60,
textAlign:'center',
fontSize:18,
fontWeight:'600'
}
});
//声明组件需要整个 store 中的哪一部分数据作为自己的 props
function selector(store) {
return {
userName:store.userName ,
password:store.password
}
}
//connect将store和组件联系在一起
export default connect(selector)(Login);
- 编写renducer reducers/LoginReducer.js
reducer是负责生成state的,所以在大项目中还会用到combineReducers 合并reducer。不过我们这个小,只有一个,就不用了。
ps:我这里后来改了个写法,所以新增了一个文件。
LoginType.js
export const LOGINUSER= 'LOGINUSER';
export const LOGINPASS='LOGINPASS';
reducers/LoginReducer.js (这里还装了个依赖redux-actions)
import {handleActions} from 'redux-actions';
import {LOGINPASS, LOGINUSER} from "./types/LoginType";
export default handleActions({
[LOGINUSER] (state, action){
return {
...state,
userName:action.userName,
}
},
[LOGINPASS] (state, action){
return {
...state,
password:action.password,
}
}
}, {
userName:'',
password:''
})
- 最后App.js 导入我们写好的login组件和reducer
import reducer from './reducers/LoginReducer';
import {Provider} from 'react-redux';
import {createStore} from 'redux';
import React, { Component } from 'react';
import Login from './screens/Login';
**let store = createStore(reducer);**
type Props = {};
export default class App extends Component<Props> {
render() {
return (
**<Provider store={store}>
<Login />
</Provider>**
)
}
}
- 结语
这样就完成这个demo了。我还在接着完善,现在在用react-navigation写登录跳转,loading啥的,所以也可以继续关注哦,写完了就放上来。
谢谢大噶看完了,一起继续努力!越努力越幸运!