xamous / react-native-smooth-pincode-input

A cross-platform, smooth, lightweight, customizable PIN code input component for React Native.
MIT License
406 stars 138 forks source link

onFulfill triggered before state update is complete #27

Open namxam opened 5 years ago

namxam commented 5 years ago

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?

ap050492 commented 5 years ago

Facing same issue

lightlii commented 5 years ago

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 :)

codeamo commented 4 years ago

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

retyui commented 4 years ago

@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
stanislav-sidorov commented 4 years ago

just upgrade, fixed

Seunope commented 4 years ago

I faced a similar issue... I used this hack, which is not necessarily the best way to solve this problem. TheonFulfill 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.

salmanitb commented 4 years ago

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

HappyCodingLover commented 4 years ago

@stanislav-sidorov which version is upgraded? Thanks.

dikmedvescekmurovec commented 4 years ago

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}
        ...
  />