简体   繁体   English

在React Native中提交表单后如何导航?

[英]How to navigate after submit a form in react native?

Here is my action creator : 这是我的动作创作者:

export const signInByPhone = ({ phone })=>{
 console.log('All props : ', this.props); // no props are coming. ??  
    return (dispatch) => {        
        fetch(`${API_URL}`, {
            method: 'POST',
            headers: {
                'Accept': 'application/json',
                'Content-Type': 'application/json',
            },
            body: JSON.stringify({
                phone_no : phone
            })
        })
        .then((res) =>res.json())
        .then((jsonRes) =>{
            if (jsonRes.code === 200) {
                console.log('json response code1 : ', jsonRes);
                // go to verification screen                                                                     
                generatOTPSuccess(dispatch,jsonRes);
            }
            else { // reset otp sending screen  
                console.log('json response code2 : ', jsonRes);
            }
        }) 
        .catch(res => generatOTPFail(dispatch, res));
    };    
}

Helper methods : 辅助方法:

const generatOTPSuccess = (dispatch, res) =>{   
    dispatch({
        type: 'OTP_GENERATE_SUCCESS',
        payload: res
    });
    this.props.navigation.navigate('OtpVerify');  
  // Error : payload: TypeError: Cannot read property 'navigation' of 
          undefined at generatOTPSuccess                                 
}

What I want to achieve , once the OTP generate successfully, It should navigate to VerifyScreen. 我要实现的目标是,一旦OTP成功生成,它应该导航到VerifyScreen。 Which I am not able to do. 我无法做到。 Can you anyone say to what could be the possible ways ? 谁能说出可能的方式吗?

On button click , I have passed following : 在单击按钮时,我已通过以下操作:

onButtonPress(){         
        const {phone}=this.props;
  console.log(phone, " :  this.props : ",this.props); // all props r coming
        this.props.signInByPhone({ phone });        
    } 

Your reducer generateOTPSuccess doesn't have access to your components' this.props 您的reducer generateOTPSuccess无法访问组件的this.props

There are 3 ways I know of to do this, the OTP_GENERATE_SUCCESS (and OTP_GENERATE_FAIL) action must change some state so you could pass that state to your component and issue the this.props.navigation.navigate('OtpVerify') call in your component when you see the change (at a guess in componentWillUpdate) 我知道有3种方法可以执行此操作,OTP_GENERATE_SUCCESS(和OTP_GENERATE_FAIL)操作必须更改某些状态,以便您可以将该状态传递给组件并在组件中发出this.props.navigation.navigate('OtpVerify')调用当您看到更改时(猜测在componentWillUpdate中)

The second way is to pass a callback to the action creator like this. 第二种方法是像这样将回调传递给动作创建者。

class Example extends Component
{
    constructor()
    {
        ....   // constructor code
        this.onSuccess = this.onSuccess.bind(this); 
        // this makes sure that this points to the component when it's ran in the action creator

    }

    ....  // component code

    onSuccess()
    {
        this.props.navigation.navigate('OtpVerify');
    }

    handleSubmit(e, loginDetails)
    {
        this.signInByPhone(loginDetails, this.onSuccess);
    }
}

Then I'd change the action creator to take an onSuccess callback 然后我将动作创建者更改为进行onSuccess回调

export const signInByPhone = ({ phone }, onSuccess)=>{
    return (dispatch) => {        
        fetch(`${API_URL}`, {
            method: 'POST',
            headers: {
                'Accept': 'application/json',
                'Content-Type': 'application/json',
            },
            body: JSON.stringify({
                phone_no : phone
            })
        })
        .then((res) =>res.json())
        .then((jsonRes) =>{
            if (jsonRes.code === 200) {
                console.log('json response code1 : ', jsonRes);
                // go to verification screen                                                                     
                generatOTPSuccess(dispatch,jsonRes);
                if(typeof(onSuccess) === 'function')
                {
                    onSuccess();
                }
            }
            else { // reset otp sending screen  
                console.log('json response code2 : ', jsonRes);
            }
        }) 
        .catch(res => generatOTPFail(dispatch, res));
    };    
}

And change generateOTPSuccess to 然后将generateOTPSuccess更改为

const generatOTPSuccess = (dispatch, res) =>{   
    dispatch({
        type: 'OTP_GENERATE_SUCCESS',
        payload: res
    });
 }

The third way is to return the promise from the fetch and handle it in the component 第三种方法是从获取中返回承诺并在组件中处理承诺

class Example extends Component
{
    constructor()
    {
        ....   // constructor code
    }

    .... //  component code

    onSuccess()
    {
        this.props.navigation.navigate('OtpVerify');
    }

    onFail()
    {
        ... // handle a fail
    }


    handleSubmit(e)
    {
        this.signInByPhone(loginDetails).then(this.onSuccess, this.onFail);
    }
}

And change signInByPhone to return the promise 并更改signInByPhone返回承诺

export const signInByPhone = ({ phone }, onSuccess)=>{
    return (dispatch) => {        
        return fetch(`${API_URL}`, {
        .... 
    }
    ....
} 

Use OTP_GENERATE_SUCCESS and OTP_GENERATE_FAIL action to change payload value or add error in state of login so you could pass that state to your component and issue the this.props.navigation.navigate('OtpVerify') call in your component's componentWillReceiveProps method. 使用OTP_GENERATE_SUCCESSOTP_GENERATE_FAIL操作更改有效载荷值或在登录状态中添加错误,以便可以将该状态传递给组件,并在组件的componentWillReceiveProps方法中发出this.props.navigation.navigate('OtpVerify')调用。

For example you have a login redux than 例如,您有一个登录redux

componentWillReceiveProps(newProps) {
    if (newProps.loggedIn) {
      this.props.navigation.navigate('OtpVerify');  
    } else if (!newProps.attempting && newProps.error) {
      showMessage(newProps.error);
    }
  }


const mapStateToProps = (state) => {
  return {
    loggedIn: !!state.login.payload,
    error: state.login.error,
    attempting: state.login.attempting
  }
};

const mapDispatchToProps = (dispatch) => {
  return {}
};

export default connect(mapStateToProps, mapDispatchToProps)(LoginScreen)

and your reducer will have logic something like that on different actions it will update state in the following way 并且你的化简器在不同的动作上会有类似的逻辑,它将以以下方式更新状态

// login attempts
const attempt = (state, action) =>
  state.merge({attempting: true});

// successful logins
const success = (state, action) =>
  state.merge({attempting: false, error: null, payload: action.payload});

// login failure
const failure = (state, action) =>
  state.merge({attempting: false, error: action.error});

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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