我正在尝试弄清楚如何在我的react-native应用程序中实现react-query。我正在通过反应查询突变执行一个简单的 firebase 登录功能。然后在我的登录组件中,我将从提交按钮调用突变。当我认为事情就这么简单时,我不断收到“错误:应该有一个队列。这可能是 React 中的一个错误。请提出问题。”但是,代码能够到达成功部分的突变。任何有关这方面的帮助将不胜感激,因为网上只有很少的指南展示了使用 firebase 实现反应查询。
这些是完整的错误:
Running "App" with {"rootTag":231,"initialProps":{}}
ERROR Warning: React has detected a change in the order of Hooks called by SignIn. This will lead to bugs and errors if not fixed. For more information, read the Rules of Hooks: https://react.dev/link/rules-of-hooks
Previous render Next render
------------------------------------------------------
1. useRef useRef
2. useState useRef
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
in SignIn (created by SignMain)
in RCTView (created by View)
in View (created by AnimatedComponent(View))
in AnimatedComponent(View)
in Unknown (created by SignMain)
in RCTView (created by View)
in View (created by AnimatedComponent(View))
in AnimatedComponent(View)
in Unknown (created by SignMain)
in RCTView (created by View)
in View (created by SignMain)
in RCTView (created by View)
in View (created by KeyboardAvoidingView)
in RCTView (created by View)
in View (created by KeyboardAvoidingView)
in KeyboardAvoidingView (created by SignMain)
in RCTScrollContentView (created by ScrollView)
in RCTScrollView (created by ScrollView)
in ScrollView (created by ScrollView)
in ScrollView (created by SignMain)
in SignMain (created by AuthNavigation)
in AuthNavigation (created by App)
in EnsureSingleNavigator
in BaseNavigationContainer
in ThemeProvider
in NavigationContainerInner (created by App)
in WithSplashScreen (created by App)
in App (created by AppWrapper)
in QueryClientProvider (created by AppWrapper)
in AppWrapper
in RCTView (created by View)
in View (created by AppContainer)
in RCTView (created by View)
in View (created by AppContainer)
in AppContainer
in App(RootComponent)
ERROR Error: Should have a queue. This is likely a bug in React. Please file an issue.
This error is located at:
in SignIn (created by SignMain)
in RCTView (created by View)
in View (created by AnimatedComponent(View))
in AnimatedComponent(View)
in Unknown (created by SignMain)
in RCTView (created by View)
in View (created by AnimatedComponent(View))
in AnimatedComponent(View)
in Unknown (created by SignMain)
in RCTView (created by View)
in View (created by SignMain)
in RCTView (created by View)
in View (created by KeyboardAvoidingView)
in RCTView (created by View)
in View (created by KeyboardAvoidingView)
in KeyboardAvoidingView (created by SignMain)
in RCTScrollContentView (created by ScrollView)
in RCTScrollView (created by ScrollView)
in ScrollView (created by ScrollView)
in ScrollView (created by SignMain)
in SignMain (created by AuthNavigation)
in AuthNavigation (created by App)
in EnsureSingleNavigator
in BaseNavigationContainer
in ThemeProvider
in NavigationContainerInner (created by App)
in WithSplashScreen (created by App)
in App (created by AppWrapper)
in QueryClientProvider (created by AppWrapper)
in AppWrapper
in RCTView (created by View)
in View (created by AppContainer)
in RCTView (created by View)
in View (created by AppContainer)
in AppContainer
in App(RootComponent), js engine: hermes
登录.tsx
function SignIn() {
const signInMutation = authAPI_login;
const validationSchema = loginValidation;
type SignInFormSchema = z.infer<typeof validationSchema>;
const {control, handleSubmit, setFocus} = useForm<SignInFormSchema>({
defaultValues: loginFormData,
resolver: zodResolver(validationSchema),
});
const onSubmit = async (data: any) => {
signInMutation.mutate({
email: data.email,
password: data.password,
});
};
return (
<View style={styles.rootContainer}>
<View style={styles.inputContainer}>
<TxtInput
height={40}
width={300}
control={control}
name="email"
placeholder="Email"
inputMode="email"
nextFocus={true}
isLoading={false}
secureTextEntry={false}
setNextFocus={() => {
setFocus('password');
}}
/>
</View>
<View style={styles.inputContainer}>
<TxtInput
height={40}
width={300}
control={control}
name="password"
placeholder="Password"
inputMode="text"
isLoading={false}
secureTextEntry={true}
/>
</View>
<Button
height={40}
width={300}
outline={true}
isListening={true}
isLoading={false}
// onPress={handleSubmit(onSubmit)}
onPress={() => {return onSubmit('test') }}
>
Sign In
</Button>
</View>
);
}
api.tsx
export async function authSV_login(email: string, password: string) {
return auth()
.signInWithEmailAndPassword(email, password)
.then((auth) => {
return true
})
.catch(error => {
if (error.code === 'auth/email-already-in-use') {
console.log('That email address is already in use!');
}
if (error.code === 'auth/invalid-email') {
console.log('That email address is invalid!');
}
return false
});
}
export const authAPI_login = useMutation({
mutationFn: ({ email, password }: {email: string, password: string}) => authSV_login(email, password),
onSuccess: async (data) => {
console.log('success', data);
},
onError: async (error) => {
console.log('error', error);
},
})
错误消息“应该有一个队列”通常表明 React 处理异步操作或状态更新的方式存在问题。在您的情况下,该错误似乎与 React Query 突变的使用有关。
检查 React Query 配置:确保您在应用程序中正确配置了 React Query。确保您已使用 包装整个应用程序并初始化查询客户端。
验证变异函数:仔细检查您的 authSV_login 函数以确保它返回 Promise 或异步函数。 Firebase提供的signInWithEmailAndPassword函数已经返回了一个Promise,所以你不需要在authSV_login中使用.then()和.catch()。
检查突变选项:检查您传递给突变函数 (authAPI_login) 的选项。确保提供所有必需的参数且格式正确。
验证登录组件:确认您的登录组件结构正确,并且按下提交按钮时是否按预期调用 onSubmit 函数。