不确定为什么这一行会引起问题。看来我正确使用了钩子。
导致错误的行是:
const { theme } = useUserContext();
getStyle
函数中的。如果删除此行,则组件加载正常。有什么想法吗?
在我看来,我正在遵守挂钩规则。
import React, {useEffect, useRef, useState} from 'react';
import { Text, Button, TextInput, View, StyleSheet, Linking } from 'react-native';
import { Formik, FormikProps, ErrorMessage } from 'formik';
import * as Yup from 'yup';
import { WideButton } from '../../../components/Buttons';
import { HeaderText, ErrorText, LinkText } from '../../../components/StyledText';
import Colors from '../../../constants/Colors';
import { useUserContext } from "../../../context/UserContext";
import { RenderErrorMessage } from "../com/FormMessage";
const LoginForm = (props) => {
const { user, logon, logoff } = useUserContext();
const [loginErrorMessage, setLoginErrorMessage] = useState("");
const usernameRef = useRef();
const onLoginSubmit = (values, actions) => {
axios.post(config.aogApiUrl + '/users/authenticate', values)
.then(res => {
//console.log(res.data);
setLoginErrorMessage("");
logon(res.data);
setShowLoginModal(false);
props.navigation.goBack();
})
.catch(error =>{
let errorMsg = error.response ? error.response.data : error.message;
setLoginErrorMessage(errorMsg);
actions.setSubmitting(false);
});
}
useEffect(() => {
usernameRef.current.focus();
});
return (
<Formik
initialValues={{ username: 'jason', password: 'Yankees1'}}
validationSchema={LoginSchema}
onSubmit={(values, actions) => {
props.onSubmit(values, actions);
}}
>
{({ handleChange, handleBlur, handleSubmit, values, errors, touched, isSubmitting }) => (
<View style={getStyle('container')} >
<HeaderText>Log in to AOG</HeaderText>
<RenderErrorMessage errorMessage={loginErrorMessage} />
<TextInput
name="username"
autoComplete="username"
ref={usernameRef}
style={getStyle('textInput')}
placeholder="Username"
onChangeText={handleChange('username')}
//onBlur={handleBlur('username')}
value={values.username} />
<ErrorMessage name="username">{msg => <ErrorText>{msg}</ErrorText>}</ErrorMessage>
<View style={{marginVertical: 5}} />
<TextInput
name="password"
autoComplete="current-password"
style={getStyle('textInput')}
placeholder="Password"
onChangeText={handleChange('password')}
//onBlur={handleBlur('password')}
value={values.password}
secureTextEntry={true}
onSubmitEditing={handleSubmit} />
<ErrorMessage name="password">{ msg => <ErrorText>{msg}</ErrorText> }</ErrorMessage>
<View style={{marginVertical: 5}} />
<View style={getStyle('submitContainer')}>
<WideButton
onPress={handleSubmit}
title="Submit"
label="Click to submit" />
</View>
<View style={getStyle('linkContainer')}>
<LinkText>Forgot password?</LinkText>
<LinkText>Forgot username?</LinkText>
<LinkText>Need to Register?</LinkText>
</View>
</View>
)}
</Formik>
);
}
const LoginSchema = Yup.object().shape({
username: Yup.string()
.min(3, 'Too Short!')
.max(15, 'Too Long!')
.required('Username is required!'),
password: Yup.string()
.min(6, 'Must be at least 6 characters')
.required('Password is required!'),
});
const getStyle = (style) => {
const { theme } = useUserContext();
const styles = {
container:{
margin: 20,
},
submitContainer: {
marginTop: 12,
marginBottom: 12
},
linkContainer:{
flex:1,
flexDirection: 'row',
alignItems: 'flex-start',
marginTop: 12,
justifyContent: 'space-between'
},
textInput:{
height: 40,
width: 'auto',
borderColor: 'gray',
backgroundColor: '#E3B39C',
borderWidth: 1,
padding: 15,
borderRadius: 20,
fontSize: 18,
margin: 5
}
}
return StyleSheet.flatten(styles[style]);
};
export default LoginForm;
答案 0 :(得分:1)
就像错误一样,根据rules of Hooks,您在getStyle
中的挂接调用无效。让我们快速检查一下规则:
仅位于React函数顶层的呼叫挂钩✅。
getStyle
在其函数主体顶部调用useUserContext()
。
从React函数组件或自定义挂钩中调用挂钩❌。
什么是React函数组件?基本上,所有功能都是通过JSX语法(例如<MyComp />
或其等效的React.createElement(MyComp, null)
)使用的。在您的情况下,getStyle
是一个普通函数,在LoginForm
组件中的某处被调用,并且包含一个Hook-因此是不允许的。您已经在useUserContext
中使用了LoginForm
,所以只需将theme
传递为getStyle
的参数:
const LoginForm = props => {
// 1. add theme here
const { user, logon, logof, theme } = useUserContext();
return (
<Formik ...>
{({ ... }) => (
// 2. everywhere you use getStyle, also pass in the theme as argument
<View style={getStyle("container", theme)}>
<HeaderText>Log in to AOG</HeaderText>
...
</View>
)}
</Formik>
);
};
// 3. Add second argument theme
const getStyle = (style, theme) => {
// do what you want with theme here
return ...
};
export default LoginForm;