2016-08-31 46 views
0

我已经对原生应用程序和redux做出了反应,其中用户在成功登录后获得了与家庭组件匹配的nevigated。但是,在通过商店接收用户配置文件之前,home组件会被渲染。如果我使用'Home'组件作为连接组件,然后重新呈现它接收配置文件。React Native + Redux组件在存储操作完成之前呈现

这是一个正确的流程,还是我能够延迟'家'的呈现,直到商店被填充新的数据。

这里是代码

类型

export const FETCH_PROFILE = 'FETCH_PROFILE'; 
export const UPDATE_PROFILE = 'UPDATE_PROFILE'; 
export const DELETE_PROFILE = 'DELETE_PROFILE'; 
export const FETCH_STREAMS = 'FETCH_STREAMS'; 

减速

export default function profile(state = {}, action) { 

    switch (action.type) { 

    case types.FETCH_PROFILE: 

    return { 
     ...state, 
     profile: action.profile 
    } 

    case types.UPDATE_PROFILE: 

    return { 
     ...state, 
     profile: action.profile 
    } 

    case types.DELETE_PROFILE: 

    return { 
     ...state, 
     profile: null 
    }; 

    default: 
    return state; 
    } 
} 

操作

var PROFILE_KEY = "@myApp:profile"; 

export function fetchProfile() { 
    return dispatch => { 
    AsyncStorage.getItem(PROFILE_KEY) 
     .then((profileString) => { 
     dispatch({ 
      type: types.FETCH_PROFILE, 
      profile: profileString ? JSON.parse(profileString) : {} 
     }) 
     }) 
    } 
} 

export function updateProfile(data) { 
    return dispatch => { 
    AsyncStorage.setItem(PROFILE_KEY, JSON.stringify(data)) 
     .then(() => { 
     dispatch({ 
      type: types.UPDATE_PROFILE, 
      profile: data 
     }) 
     }) 
    } 
} 

export function deleteProfile() { 
    return dispatch => { 
    AsyncStorage.removeItem(PROFILE_KEY) 
     .then(() => { 
     dispatch({ 
      type: types.DELETE_PROFILE 
     }) 
     }) 
    } 
} 

登录组件

class Login extends React.Component { 

    constructor(props) { 
    super(props); 
    this.state = { 
     username: "", 
     password: "", 
     error: "", 
     showProgress: false, 
    }; 
    } 

    _focusNextField(nextField) { 
    this.refs[nextField].focus(); 
    } 

    _onLoginPressed() { 
    this.setState({showProgress: true}); 
    this._login(); 
    } 

    async _login() { 
    try { 
     let response = await fetch(BASE_URL + url, { 
          method: 'POST', 
          headers: { 
           'Accept': 'application/json', 
           'Content-Type': 'application/json', 
          }, 
          body: JSON.stringify({ 
           user: { 
           email: this.state.username, 
           password: this.state.password, 
           } 
          }) 
          }); 

     let res = await response.text(); 
     if (response.status >= 200 && response.status < 300) { 
      let user = JSON.parse(res); 
      this.props.updateProfile(user.user); 
      this.setState({showProgress: false}); 
      this.props.navigator.replace({name: 'Home'}); 
     } 
     else { 
     let error = JSON.parse(res); 
     throw error.errors; 
     } 
    } catch(error) { 
     this.setState({error: error}); 
     this.setState({showProgress: false}); 
     console.log("error " + error); 
    } 
    } 

    render() { 
    return (
     <View style={styles.loginBox}> 
      <TextInput 
      ref="username" 
      value={this.state.username} 
      placeholder="Username" 
      keyboardType="email-address" 
      onChangeText={(username) => this.setState({username}) } 
      onSubmitEditing={() => this._focusNextField('password')}/> 
      <TextInput 
      ref="password" 
      placeholder="Password" 
      value={this.state.password} 
      secureTextEntry={true} 
      onChangeText={(password) => this.setState({password}) } 
      returnKeyType="go"/> 
      <Button textStyle={{fontSize: 14}} onPress={this._onLoginPressed.bind(this)} style={{marginTop: 30}}> 
      Sign In 
      </Button> 
     </View> 
    ); 
    } 
} 

const styles = StyleSheet.create({ 
    loginBox: { 
    flex: 1, 
    justifyContent: 'center', 
    alignItems: 'center', 
    alignItems: 'stretch', 
    margin: 10, 
    } 
}); 

var {updateProfile} = require('../Actions'); 
import { bindActionCreators } from 'redux'; 
import { connect } from 'react-redux'; 

module.exports = connect(
    null, 
    (dispatch) => { 
    return bindActionCreators({updateProfile}, dispatch) 
    } 
)(Login) 

首页

class Home extends React.Component { 

    render() { 
    return (
     <View style={{flex: 1, backgroundColor: '#fff'}}> 
     <Text style={{margin: 10, fontSize: 15, textAlign: 'left'}}>I'm in the Drawer!</Text> 
     <Text>Auth key : {this.props.profile ? this.props.profile.authentication_token : 'authentication_token'}</Text> 
     </View> 
    ); 
    } 
} 

//module.exports = Home; 

import { connect } from 'react-redux'; 

module.exports = connect(
    (state) => { 
    return { 
     profile: state.profile 
    } 
    }, 
    null 
)(Home) 
+0

你为什么不只是显示在'繁忙的微调'直到组件接收它所需要的数据......这心不是一个真正的问题作出反应的只是性质异步软件 – Maxwelll

+0

我正在做,但再次在我正在推销另一个组件,为此我需要配置文件来进行另一个API调用。这有点困难。但给出的解决方案真的很棒,并感谢@ caojs –

回答

2

如果您使用redux-thunk,可以直到数据被加载延迟的转变。你需要改变一些小东西。

return添加到动作创建者。

export function updateProfile(data) { 
    return dispatch => { 
    return AsyncStorage.setItem(PROFILE_KEY, JSON.stringify(data)) 
     .then(() => { 
     dispatch({ 
      type: types.UPDATE_PROFILE, 
      profile: data 
     }) 
     }) 
    } 
} 

添加await

if (response.status >= 200 && response.status < 300) { 
    let user = JSON.parse(res); 
    await this.props.updateProfile(user.user); 
    this.setState({showProgress: false}); 
    this.props.navigator.replace({name: 'Home'}); 
} 
相关问题