Reactjs 更改react组件中Firebase.on的子目标,并停止侦听对上一个子目标的更改

Reactjs 更改react组件中Firebase.on的子目标,并停止侦听对上一个子目标的更改,reactjs,firebase,firebase-realtime-database,Reactjs,Firebase,Firebase Realtime Database,我正在尝试将Firebase用于聊天应用程序 我正在尝试在当前选定的邮件上设置一个侦听器,以检查是否有新邮件到达 在我的“MessageBody”组件上,我使用.On(“value”)设置了一个实时侦听器。代码如下: MessageBody.js class MessageBody extends Component { getMessages = (turnOffRef) => { const db = firebase.database();

我正在尝试将Firebase用于聊天应用程序

我正在尝试在当前选定的邮件上设置一个侦听器,以检查是否有新邮件到达

在我的“MessageBody”组件上,我使用.On(“value”)设置了一个实时侦听器。代码如下:

MessageBody.js

class MessageBody extends Component {

    getMessages = (turnOffRef) => {
        const db = firebase.database();
        const newMessageRef = db.ref().child('messages').child(this.props.currentChatId);
        newMessageRef.on('value', snap => {
        console.log("CHAT ID IN SNAP: ", this.props.currentChatId);
        this.props.onGotMessageContent(snap.val());
        });
    };

    componentDidMount() {
        this.getMessages();
    }

//... other unrelated code

    const mapDispatchToProps = dispatch => {
    return {
        onGotMessageContent: (messages) => dispatch(actions.setMessageContent(messages)),
    };
};
redux message action.js

export const setMessageContent = (messages) => {
    return {
        type: actionTypes.ADD_SELECTED_CHAT_TO_STATE,
        messages: messages,
    };
};
Redux消息缩减器:

const addSelectedChatToState = (state, action) => {
    return {
        ...state,
        currentMessage: action.messages,
    };
};

// other code...

const reducer = (state = initialState, action) => {
    switch(action.type) {
        // other cases:... 
        case actionTypes.ADD_SELECTED_CHAT_TO_STATE: return newMessageReceived(state, action);
        default: return state;
    }
};

这将接收当前所选“消息”子项的实时更新。但是,如果我以前一直在收听另一条消息(通过道具发送到MessageBody),则在任何一条消息收到更新时,我都会收到一个快照事件

因此,在上面的例子中,我之前听过“-L3ylXhU3zSNvPB3h_uS”,然后通过道具发送了一个新的“-L3ylh4b4yuSRvYkH1ai”参考。但现在,只要消息的任何一个子项有更新,我就会收到更新,而我只希望更新当前this.props.CurrentChatId

如果我首先进入聊天室“-L3ylXhU3zSNvPB3h_uS”,我会在控制台中看到以下内容:

CHAT ID IN SNAP:  -L3ylXhU3zSNvPB3h_uS
CHAT ID IN SNAP:  -L3ymmWaLe9qCmAeJlO7
CHAT ID IN SNAP:  -L3ylXhU3zSNvPB3h_uS
然后,如果我进入聊天室“-L3ymmWaLe9qCmAeJlO7”,我会在控制台中看到以下内容:

CHAT ID IN SNAP:  -L3ylXhU3zSNvPB3h_uS
CHAT ID IN SNAP:  -L3ymmWaLe9qCmAeJlO7
CHAT ID IN SNAP:  -L3ylXhU3zSNvPB3h_uS
但是,如果在我仍在L3ymmWaLe9qCmAeJlO7中时,通过消息L3ylXhU3zSNvPB3h_uS向我发送消息,我会在控制台中获得以下信息:

CHAT ID IN SNAP:  -L3ylXhU3zSNvPB3h_uS
CHAT ID IN SNAP:  -L3ymmWaLe9qCmAeJlO7
CHAT ID IN SNAP:  -L3ylXhU3zSNvPB3h_uS

是否有一种方法可以在更改子项时关闭旧的侦听器,但保持当前侦听器处于活动状态以获取此子项中的新消息?

我希望这能对您有所帮助

我将消息引用声明为类(组件)的属性,然后在
getMessages
中,如果已经设置了侦听器,我将停止侦听,然后再次侦听新的chatId,我添加
componentWillReceiveProps
,因此当props更改时,使用新的props再次调用
getMessages
,此外,当组件将卸载时,应停止侦听器

签出代码

class MessageBody extends Component 
{
    consrtuctor(props){
        super(props);
        this.messageRef = null;
    }

    getMessages = (chatId) => {

        if(this.messageRef)
            this.messageRef.off();

        const db = firebase.database();
        this.messageRef = db.ref().child('messages').child(this.props.currentChatId);
        this.messageRef.on('value', snap => {
            console.log("CHAT ID IN SNAP: ", this.props.currentChatId);
            this.props.onGotMessageContent(snap.val());
        });
    };

    componentDidMount() {
        let chatId = this.props.currentChatId;
        this.getMessages(chatId);
    }

    componentWillReceiveProps(nextProps){
        let chatId = nextProps.currentChatId;
        this.getMessages(chatId);   
    }

    componentWillUnmount(){
        if(this.messageRef)
            this.messageRef.off();
    }

    //.....other code

};

您对引用使用
off
方法来停止侦听,例如
messageRef.off()
Thank Ali,这不会也关闭当前侦听器吗?我想杀死当前的侦听器并替换为新的id。我将在componentWillReceiveProps中玩一玩,看看我是否能解决问题。你能发布
onGetMessageContent的代码吗?
当然,我编辑了,希望能更好地解释。太好了!非常感谢你花时间帮助阿里。非常感谢。很高兴帮助您:)