react-native-smooth-pincode-input icon indicating copy to clipboard operation
react-native-smooth-pincode-input copied to clipboard

onFulfill triggered before state update is complete

Open namxam opened this issue 5 years ago • 9 comments

I copied the example code and added set code length to 5. onTextChange is triggering a state change. onFulfill is reading state and rendering an alert. Unfortunately, the state update seems to be slower and therefore I only get the first 4 letters of entered code.

Any ideas how to prevent this?

namxam avatar Jul 30 '19 14:07 namxam

Facing same issue

ap050492 avatar Aug 09 '19 06:08 ap050492

I've come into this problem but it's worth mentioning that onFulfill receives the final value as it's only argument so you don't need to use the code value set in state by onTextChange for anything other than passing the value back to the component. Hope that makes sense :)

lightlii avatar Aug 10 '19 13:08 lightlii

Hey everyone, @xamous onFulfill is triggering before it receives the last character of the state. any help on how this issue was solved? example code of mine is as below: ` const dispatchAction = signIn => { if (signIn) { dispatchLogin(); } else { dispatchSignUp(); } };

<SmoothPinCodeInput containerStyle={styles.spacer} password mask="﹡" ref={otpRef} cellStyle={{ borderBottomWidth: 2, borderColor: 'gray' }} cellStyleFocused={{ borderColor: 'black' }} value={password.password} cellSpacing={40} maskDelay={0} cellSize={60} keyboardType="number-pad" codeLength={4} autoFocus onTextChange={pin => setPassword({ password: pin })} onFulfill={dispatchAction()} />

` Thanks

codeamo avatar Feb 04 '20 18:02 codeamo

@namxam

Thanks for reporting and you can also use better implementation with better maintainability: https://github.com/retyui/react-native-confirmation-code-field

react-native-confirmation-code-field animated example react-native-confirmation-code-field mask example react-native-confirmation-code-field underline example react-native-confirmation-code-field basic example

retyui avatar Apr 28 '20 14:04 retyui

just upgrade, fixed

stanislav-sidorov avatar May 10 '20 08:05 stanislav-sidorov

I faced a similar issue... I used this hack, which is not necessarily the best way to solve this problem. The onFulfill calls this function doSomething. I set a time in doSomething function before the code is printed out. This will allow the state to update before the code is printed out.

<SmoothPinCodeInput
         cellStyle={styles.pinCode}
         cellStyleFocused={styles.pinCodeFocus}
          value={code}
          onTextChange={code => this.setState({code})}
          onFulfill={this.doSomething}
  />

The doSomething function

doSomething =  () => {
      setTimeout( () => {
         const {code} = this.state;
         console.log(code)
     }, 500);
  };

I delay the action for 500 milliseconds before the correct code was printed out. Like I said earlier, I don't think this is the best way to fix the issue because how can we be sure the state will have updated within 500 milliseconds. But this hack is a walk around the bug. Another option will be to put a button and let the user trigger the doSomething function.

Seunope avatar Aug 04 '20 15:08 Seunope

@stanislav-sidorov upgrade what?? version of this library?

salmanitb avatar Aug 05 '20 08:08 salmanitb

@stanislav-sidorov which version is upgraded? Thanks.

HappyCodingLover avatar Oct 06 '20 18:10 HappyCodingLover

The solution is to simply use the variable given to the onFullfill callback. This way you always get the entire input in the doSomethingElse function. The issue lies in asynchronicity. State setting is asynchronous and there is no way of knowing when it will finish. That is why I believe onFulfill is called before your states are set.

<SmoothPinCodeInput
         ...
          onTextChange={(pin) => doSomething({pin})}
          onFulfill={(fulfilledPIN) => doSomethingElse(fulfilledPIN}
        ...
  />

dikmedvescekmurovec avatar Oct 16 '20 10:10 dikmedvescekmurovec