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)}
我对 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)}