2016-08-31 49 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'}); 
} 
相關問題