反应挂钩问题,无法创建聊天室

Problem with react hooks, cant create a chatroom

我正在尝试使用突变和反应挂钩创建聊天室。我找不到解决我遇到的错误的方法。错误是:无效的钩子调用。钩子只能在函数组件的主体内部调用。这可能是由于以下原因之一造成的:

  1. 您的 React 和渲染器版本可能不匹配(例如 React DOM)
  2. 您可能违反了 Hooks 规则
  3. 您可能在同一个应用程序中有多个 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 可以帮助您发现此类错误