首页 > 解决方案 > 无效的挂钩调用。钩子只能在功能组件的主体内部调用

问题描述

我正在尝试创建诸如监视数据库(RabbitMQ)的后台工作者之类的东西。如果有新条目,它将在 UI 中通知用户。

我从 appbar 调用我的“后台工作人员”:

<AppBar>
    <BGWorker />
</AppBar>

这是我的BGWorker.js

import { Notify } from 'Notify.ts';

const { Client } = require('@stomp/stompjs');

class BGWorker extends Component {
    componentDidMount(){
        this.client = new Client();
        this.client.configure({
            brokerURL: 'ws://192.168.1.5:15555/ws',
            connectHeaders:{
                login: "guest",
                passcode: "guest"
            },

            onConnect: () => {
                this.client.suscribe('exchange/logs', message => {
                    console.log(message.body);       //yes this does print out correctly
                    Notify(message.body, 'info');    //error here
            },
        });

        this.client.activate();
    }

    render(){
        return (
            <div/>
        );
    }
}

export default BGWorker

这是我在Notify.ts中的通知功能

import { useDispatch } from 'react-redux';
import { showNotification } from 'react-admin';

export const Notify = (msg:string, type:string='info') => {
    const dispatch = useDispatch();

    return () => {
        dispatch(showNotification(msg, type)); //this will call React-Admin's showNotification function
        //... and other stuff
    };
};

但是每当有条目进入时,我都会收到“无效的挂钩调用。挂钩只能在功能组件的主体内调用。 ”我该如何解决这个问题?我阅读了反应文档并尝试使用自定义钩子,但效果不佳(不确定我是否正确执行):

function useFoo(client){ 
    if(client !== undefined)
    {
        client.suscribe('exchange/logs', message => { //I get an 'Uncaught (in promise) TypeError: Cannot read property of 'subscribe' of undefined
            Notify(message.body, 'info');
        },
    }
}

class BGWorker extends Component {
    ...
    onConnect: useFoo(this.client);
    ...
}

标签: reactjsreact-admin

解决方案


为了使用钩子,您应该将您的类转换为功能组件。我假设您不了解钩子和功能组件。

该博客将帮助您了解转换的细微差别-> https://nimblewebdeveloper.com/blog/convert-react-class-to-function-component

其次,你需要知道钩子是如何工作的。参考这个-> https://reactjs.org/docs/hooks-intro.html

function BGWorker() {
  const dispatch = useDispatch();

  React.useEffect(() => {
       const client = new Client();
       client.configure({
            brokerURL: 'ws://192.168.1.5:15555/ws',
            connectHeaders:{
                login: "guest",
                passcode: "guest"
            },

            onConnect: () => {
                client.suscribe('exchange/logs', message => {
                    // dispatch your actions here
                    dispatch()
            }),
        });

        client.activate();
  }, []);

  return <div />
}

最好读几篇博客,看几篇教程,了解钩子和函数式组件。然后尝试解决你的问题。

您可能会在这里找到答案,从长远来看,您需要了解它们。


推荐阅读