简体   繁体   中英

React Native Redux how can I update UI, navigate to new screen after call API that without used flag

I'm developing a mobile application by use react-native and redux,thunk and it's the first time I write by react-native.

My problem is I call an api and the response is valid, I want to do somethings as update UI, navigate to new screen... for do that I will need to used flag in my component to mark it.

This is login example, after user login success, i want to navigate to Home screen. for do that, i need check an flag isLoginSuccess in props on the method componentWillReceiveProps to know user have been login success or not, but i think it's not good solution.

My question is we have other way to do it without use flag.

action.js

export const LOGIN_SUCCESS = "LOGIN_SUCCESS";
export const LOGIN_FAIL = "LOGIN_FAIL";
export const LOGIN = "LOGIN";

export function login(username, password) {
    console.log(username)
    return {
        type: LOGIN,
        username: username,
        password: password
    }
}

export function loginSuccess(data) {
    return {
        type: LOGIN_SUCCESS,
        loginData: data
    }
}

export function loginFail(error) {
    return {
        type: LOGIN_FAIL,
        error: error
    }
}

export function doLogin(username, password) {
    return (dispatch) => {
        dispatch(login(username, password))
        api.login(username, password)
            .then(response => response.json())
            .then(jsonData => {
                console.log(jsonData)
                dispatch(loginSuccess(jsonData))
            })
            .catch((error) => {
                dispatch(loginFail(error))
            })
    }
}

reducer.js

const initialState = {
    loginData:{},
    isLoginDoing : false,
    isLoginSuccess : false,
    username :"",
    password : "",
    error : {},
}

export default function(state = initialState , action ={}){
   switch(action.type){
       case actionType.LOGIN:{
            return {
                ...state,
                username: action.username,
                password: action.password,
                isLoginDoing : true
            }
       }
       case actionType.LOGIN_SUCCESS:{
            return {
                ...state,
                loginData: action.loginData,
                isLoginDoing : false,
                isLoginSuccess : true
            }
       }
       case actionType.LOGIN_FAIL:{
            return {
                ...state,
                isLoginDoing : false,
                isLoginSuccess : false,
                error : action.error
            }
       }
       default :{
           return state
       }
   }
}

component.js

import { connect } from "react-redux"
import { bindActionCreators } from 'redux';
import { doLogin } from '../actions'
import BaseComponent from './baseComponent'   
 class Login extends BaseComponent {
  constructor(props) {
    super(props)
    this.state = {
      username: '',
      password: '',
    }
    this.functionLogin = this.functionLogin.bind(this);
  }

  functionLogin() {
    const { username, password } = this.state;
    if(!this.props.loginReducer.isLoginDoing){
    this.props.doLogin(username, password)
    }
  }
  componentWillReceiveProps (nextProps) {
     console.log("componentWillReceiveProps");
      const { navigate, goBack } = this.props.navigation;
     if(nextProps.loginReducer.isLoginSuccess){
        // this._navigateTo('Home')
        navigate('Home',nextProps.loginReducer.loginData);
     }
  }
  render() {
    const { navigate, goBack } = this.props.navigation;
    return (
      <View style={{ backgroundColor: 'color', marginTop: 10 }} >
        <TextInput
          style={{ height: 40 }}
          placeholder="Username"
          onChangeText={value => this.setState({ username: value })}
        />
        <TextInput
          style={{ height: 40 }}
          placeholder="Password"
          onChangeText={value => this.setState({ password: value })}
        />
        <Button
          onPress={this.functionLogin}
          title="Login"
          color="#841584"
        />
      </View>
    );
  }
}

const mapStateToProps = (state) => {
  console.log(state);
  return {
    loginReducer: state.loginReducer
  };
}
function mapDispatchToProps(dispatch) {
  return {
    doLogin: (username, password) => dispatch(doLogin(username, password))
  }
}
export default connect(mapStateToProps, mapDispatchToProps)(Login)

Thanks

In your function doLogin, you can dispatch a navigation action after dispatch(loginSuccess(jsonData)) .

For example for react-navigation (if you have integrated it with redux, if it's not the case, see https://reactnavigation.org/docs/guides/redux ):

dispatch(NavigationActions.navigate({routeName: 'Home'});

(Don't forget import { NavigationActions } from 'react-navigation'; )

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM