反应挂钩问题,无法创建聊天室
Problem with react hooks, cant create a chatroom
我正在尝试使用突变和反应挂钩创建聊天室。我找不到解决我遇到的错误的方法。错误是:无效的钩子调用。钩子只能在函数组件的主体内部调用。这可能是由于以下原因之一造成的:
- 您的 React 和渲染器版本可能不匹配(例如 React DOM)
- 您可能违反了 Hooks 规则
- 您可能在同一个应用程序中有多个 React 副本
下面是 hook.ts 文件和我的屏幕的 2 个代码示例
import { getStateFromPath } from '@react-navigation/native';
import axios from 'axios';
import { useQuery, useMutation } from 'react-query';
import { useSelector } from 'react-redux';
import { Chatroom } from '../entities/Chatroom';
function helper() {
const token = useSelector((state: any) => state.user.idToken)
return {token};
}
const baseURL = "";
export const useFetchChatrooms = () => {
var { token } = helper()
const fetchChatrooms = async() => {
return await axios.get(baseURL + token)
}
const {isLoading, isError, data, error} = useQuery('chatrooms', fetchChatrooms)
let chatrooms: Chatroom[] = []
for(const key in data?.data) {
const chatroom = data?.data[key]
chatrooms.push(new Chatroom(chatroom.title, chatroom.status.UNREAD, '', new Date()))
}
return{
isLoading, isError, chatrooms, error
}
}
export const usePostChatrooms = () => {
return useMutation((newChatroom: Chatroom) => {
var { token } = helper()
return axios.post(baseURL + token, newChatroom)
})
}
还有屏幕。
import React from 'react';
import { FlatList, StyleSheet, Text, View, TextInput, Button } from 'react-native';
import { useFetchChatrooms, usePostChatrooms } from '../hooks/rqhooks';
import { useNavigation } from '@react-navigation/native';
import { NativeStackNavigationProp } from '@react-navigation/native-stack';
import { StackParamList } from "../typings/navigations";
import { useMutation, useQueryClient } from 'react-query';
import { Chatroom, Status } from '../entities/Chatroom';
type ScreenNavigationType = NativeStackNavigationProp<
StackParamList,
"ReactQueryScreen"
>
export default function ReactQueryScreen() {
const [title, onChangeTitle] = React.useState('');
const navigation = useNavigation<ScreenNavigationType>()
const { isLoading, isError, chatrooms, error} = useFetchChatrooms();
const queryClient = useQueryClient();
// Mutations
const {mutate: createChatroom} = usePostChatrooms()
if(isLoading) {
return <Text>Loading...</Text>
}
if(isError) {
return <Text>Error: {error}</Text>
}
const renderChatroom = ({ item }: { item: any }) => (
<Text>{item.title}</Text>
);
const rqHandleAddChatroom = () => {
const chatroom: Chatroom = new Chatroom(title, Status.UNREAD, '', new Date());
createChatroom(chatroom, {onSuccess: () => queryClient.invalidateQueries('chatrooms')})
}
return (
<View style={styles.container}>
<FlatList
data={chatrooms}
renderItem={renderChatroom}
keyExtractor={(index) => index.toString()}
/>
<Text>react query</Text>
<TextInput
onChangeText={onChangeTitle}
value={title}
placeholder="Chatroom name"
/>
<Button onPress={rqHandleAddChatroom} title="Create chatroom"/>
</View>
);
}
const styles = StyleSheet.create({
container: {
flex: 1,
backgroundColor: '#fff',
alignItems: 'center',
justifyContent: 'center',
},
})
名为 helper
的函数调用 useSelector
。根据 rules of hooks,只能调用 Hooks:
- 来自功能组件
- 来自自定义挂钩
自定义挂钩是以单词 use
开头的函数。所以你只需要将 helper
重命名为 useHelper
- function helper() {
+ function useHelper() {
const token = useSelector((state: any) => state.user.idToken)
return {token};
}
然后将其命名为:
var { token } = useHelper()
这些调用再次有效,因为它们也是在自定义挂钩中进行的 (usePostChatrooms
)。
React 团队 eslint plugin 可以帮助您发现此类错误
我正在尝试使用突变和反应挂钩创建聊天室。我找不到解决我遇到的错误的方法。错误是:无效的钩子调用。钩子只能在函数组件的主体内部调用。这可能是由于以下原因之一造成的:
- 您的 React 和渲染器版本可能不匹配(例如 React DOM)
- 您可能违反了 Hooks 规则
- 您可能在同一个应用程序中有多个 React 副本
下面是 hook.ts 文件和我的屏幕的 2 个代码示例
import { getStateFromPath } from '@react-navigation/native';
import axios from 'axios';
import { useQuery, useMutation } from 'react-query';
import { useSelector } from 'react-redux';
import { Chatroom } from '../entities/Chatroom';
function helper() {
const token = useSelector((state: any) => state.user.idToken)
return {token};
}
const baseURL = "";
export const useFetchChatrooms = () => {
var { token } = helper()
const fetchChatrooms = async() => {
return await axios.get(baseURL + token)
}
const {isLoading, isError, data, error} = useQuery('chatrooms', fetchChatrooms)
let chatrooms: Chatroom[] = []
for(const key in data?.data) {
const chatroom = data?.data[key]
chatrooms.push(new Chatroom(chatroom.title, chatroom.status.UNREAD, '', new Date()))
}
return{
isLoading, isError, chatrooms, error
}
}
export const usePostChatrooms = () => {
return useMutation((newChatroom: Chatroom) => {
var { token } = helper()
return axios.post(baseURL + token, newChatroom)
})
}
还有屏幕。
import React from 'react';
import { FlatList, StyleSheet, Text, View, TextInput, Button } from 'react-native';
import { useFetchChatrooms, usePostChatrooms } from '../hooks/rqhooks';
import { useNavigation } from '@react-navigation/native';
import { NativeStackNavigationProp } from '@react-navigation/native-stack';
import { StackParamList } from "../typings/navigations";
import { useMutation, useQueryClient } from 'react-query';
import { Chatroom, Status } from '../entities/Chatroom';
type ScreenNavigationType = NativeStackNavigationProp<
StackParamList,
"ReactQueryScreen"
>
export default function ReactQueryScreen() {
const [title, onChangeTitle] = React.useState('');
const navigation = useNavigation<ScreenNavigationType>()
const { isLoading, isError, chatrooms, error} = useFetchChatrooms();
const queryClient = useQueryClient();
// Mutations
const {mutate: createChatroom} = usePostChatrooms()
if(isLoading) {
return <Text>Loading...</Text>
}
if(isError) {
return <Text>Error: {error}</Text>
}
const renderChatroom = ({ item }: { item: any }) => (
<Text>{item.title}</Text>
);
const rqHandleAddChatroom = () => {
const chatroom: Chatroom = new Chatroom(title, Status.UNREAD, '', new Date());
createChatroom(chatroom, {onSuccess: () => queryClient.invalidateQueries('chatrooms')})
}
return (
<View style={styles.container}>
<FlatList
data={chatrooms}
renderItem={renderChatroom}
keyExtractor={(index) => index.toString()}
/>
<Text>react query</Text>
<TextInput
onChangeText={onChangeTitle}
value={title}
placeholder="Chatroom name"
/>
<Button onPress={rqHandleAddChatroom} title="Create chatroom"/>
</View>
);
}
const styles = StyleSheet.create({
container: {
flex: 1,
backgroundColor: '#fff',
alignItems: 'center',
justifyContent: 'center',
},
})
名为 helper
的函数调用 useSelector
。根据 rules of hooks,只能调用 Hooks:
- 来自功能组件
- 来自自定义挂钩
自定义挂钩是以单词 use
开头的函数。所以你只需要将 helper
重命名为 useHelper
- function helper() {
+ function useHelper() {
const token = useSelector((state: any) => state.user.idToken)
return {token};
}
然后将其命名为:
var { token } = useHelper()
这些调用再次有效,因为它们也是在自定义挂钩中进行的 (usePostChatrooms
)。
React 团队 eslint plugin 可以帮助您发现此类错误