react-native react-thunk 在初始组件加载和输入上的任何按键时触发

react-native react-thunk triggering on initial component load and any keypress on an input

我对 React、react-native、react-redux 和 react-thunk 有点陌生,遇到了这个我无法解释的奇怪问题。

我有一个使用 thunk 来验证用户身份的登录组件。我 mapDispatchToProps 并将其应用于组件,但出于某种原因,每次组件呈现时,它都会触发 thunk,然后在任一输入字段中的每个按键之后,也会触发 thunk。这会创建无数次对身份验证的调用 API,但都失败了。

什么会导致这种行为?

const SignIn = ({navigation, signIn}: any): React.ReactElement => {
  const [username, setUsername] = React.useState<string>('');
  const [password, setPassword] = React.useState<string>('');
  const [passwordVisible, setPasswordVisible] = React.useState<boolean>(false);

  const onForgotPasswordButtonPress = (): void => {
    navigation && navigation.navigate('Forgot Password');
  };

  const onPasswordIconPress = (): void => {
    setPasswordVisible(!passwordVisible);
  };

  const passwordInput = useRef() as React.MutableRefObject<any>;

  return (
    <KeyboardAvoidingView>
      <ImageOverlay
        style={styles.container}
        source={require('../assets/images/image-background3.jpg')}>
        <SafeAreaView style={styles.container}>   
          <View style={styles.formContainer}>
            <Input
              status="control"
              placeholder="Username"
              autoCapitalize={'none'}
              autoCompleteType={'off'}
              autoCorrect={false}
              autoFocus={false}
              icon={PersonIcon}
              value={username}
              onChangeText={setUsername}
              returnKeyType={'next'}
              blurOnSubmit={false}
              onSubmitEditing={() => passwordInput.current.focus()}
            />
            <Input
              ref={passwordInput}
              style={styles.passwordInput}
              status="control"
              placeholder="Password"
              autoCapitalize={'none'}
              autoCompleteType={'off'}
              autoCorrect={false}
              icon={passwordVisible ? EyeIcon : EyeOffIcon}
              value={password}
              secureTextEntry={!passwordVisible}
              onChangeText={setPassword}
              onIconPress={onPasswordIconPress}
              onSubmitEditing={() => signIn(username, password)}
            />
            <View style={styles.forgotPasswordContainer}>
              <Button
                style={styles.forgotPasswordButton}
                appearance="ghost"
                status="control"
                onPress={onForgotPasswordButtonPress}>
                Forgot your password?
              </Button>
            </View>
          </View>
          <Button
            style={styles.signInButton}
            status="control"
            size="large"
            disabled={username.length === 0 || password.length === 0}
            onPress={signIn(username, password)}>
            Sign In
          </Button>
        </SafeAreaView>
      </ImageOverlay>
    </KeyboardAvoidingView>
  );
};

const mapDispatchToProps = (dispatch: any) => ({
  signIn: (username: string, password: string) =>
    dispatch(signInThunk(username, password)),
});

export const SignInScreen = connect(
  null,
  mapDispatchToProps,
)(SignIn);

砰的一声:

export const signInThunk = (username: string, password: string) => {
  return async (dispatch: any) => {

    try {
      dispatch(isLoading(true));

      const userData = await fetch(Providers.auth, {...})
        .then(response => response.json())
        .then(() => dispatch(isLoading(false)));

      if(userData.token){
       dispatch(signInAction(userData.token));
       dispatch(updateProfileAction(userData));
      }

      dispatch(isLoading(false));
    } catch (error) {
      console.error(error);
    }
  };
};

这是常见错误,只需更改:

onPress={signIn(username, password)}

onPress={() => signIn(username, password)}