【问题标题】:How to fix "dispatch is not a function" error in react native project如何修复反应原生项目中的“调度不是函数”错误
【发布时间】:2020-08-07 10:51:22
【问题描述】:

在 react-native、redux、firebase 项目中,我有一个抽屉组件,它在组件挂载时订阅 onSnapshot 侦听器,并且在卸载时,它调用快照引用。这个组件看起来像这样:

import { onAccountChange } from '../actions/Agenda';    
import {dispatch} from 'redux';

class DrawerContentComponent extends React.Component {
    constructor (props) {
        super(props);
    }
    componentDidMount(){
        this.unsubscribeAccount = firebase.firestore().collection('users').doc(this.props.authUser.uid).onSnapshot((doc) => {
        dispatch({type: types.LOAD_ACCOUNT, payload: doc.data()})

    });
    }
    componentWillUnmount() {
        this.unsubscribeAccount();
    }

    < ...rest of component... >

EDIT:
    const mapStateToProps = ({ account, auth, inbox, agenda }) => {
    const { role, profileImg, legalName, username, rating, phoneNumber } = account;
    const { conversations } = inbox;
    const { authUser } = auth;
    const { events } = agenda;
    return {
        role,
        profileImg,
        legalName,
        username,
        rating,
        phoneNumber,
        authUser,
        conversations,
        events
    };
};

    const mapDispatchToProps = { logoutUser, onProfileChange, onAccountChange, getConversations, getAgenda };

    export default connect(mapStateToProps, mapDispatchToProps)(DrawerContentComponent);
} 

编辑:onAccountChange()

export const onAccountChange = (uid) => {
    return (dispatch) => {
      firebase.firestore().collection('users').doc(uid).onSnapshot((doc) => {
        dispatch({ type: types.LOAD_ACCOUNT, payload: doc.data() });
      });
    };
};

上述功能是必要的,因为我无法取消订阅该操作,该操作以前放置在外部目录中以进行操作。

问题:我希望能够以某种方式使用已在操作文件 (getAgenda()) 中创建的函数来实现这一点,而不必重写组件中的代码,因为我目前这样做只是为了有能力在卸载时取消订阅侦听器,这是我想使它工作的唯一方法。

理想情况下,id 喜欢做这样的事情:

componentDidMount() {
  this.unsubscribeAgenda = this.props.getAgenda();
}
componentWillUnmount() {
  this.unsubscribeAgenda();
}

但是上面的结果是: TypeError: 'dispatch is not a function' 如果我取出 dispatch 导入,错误是 ReferenceError: Cant find variable: dispatch,我显然需要为 onSnapshot 侦听器调度更改

有什么策略可以解决这个问题?

【问题讨论】:

  • 你的 getAgenda 动作创建者是什么样的?
  • 我没有一个,我从来不需要一个。我在另一个目录中有我的操作,最初只是通过道具在挂载时调用它们。但这并不能帮助我不得不调用对 onSnapshot 侦听器的引用来分离它并防止应用崩溃
  • 你能贴出getAgenda的代码是什么吗?
  • @ZacharyHaber 现在检查一下,为了简洁,用 onAccountChange 代替,相同的概念,更少的代码

标签: firebase react-native redux react-redux


【解决方案1】:

你不能直接从 redux 导入 dispatch。

您需要使用 react-redux 的 connect() 函数将您的动作创建者与 dispatch 包装起来,或者直接从中获取 dispatch。

如果您使用的是功能组件,您可以使用useDispatch 来访问它。

如果您不想使用常规的 react-redux 选项之一,您可以从您的商店导出调度,然后从您创建商店的位置导入它。

export const dispatch = store.dispatch

如果您的 firestore 的大部分逻辑都在 redux thunk 操作中(或具有异步功能的类似操作),请使用 connect 将操作包装在 dispatch 中,然后按照您的理想运行它。从 thunk 操作返回的任何内容也会从调用中返回,因此您应该能够将其设置为返回取消订阅功能。

 connect({},{onAccountChange})(DrawerContentComponent)

然后您可以使用以下方式调度 onAccountChange 操作创建者:

this.props.onAccountChange()

编辑:

将您的 onAccountChange 函数修改为此,以便您的 thunk 返回您的取消订阅函数。

export const onAccountChange = (uid) => {
  return (dispatch) => {
    return firebase
      .firestore()
      .collection('users')
      .doc(uid)
      .onSnapshot((doc) => {
        dispatch({ type: types.LOAD_ACCOUNT, payload: doc.data() });
      });
  };
};

然后您只需将 onAccountChange 添加到 mapDispatch 到 props 并在您的 componentDidMount 方法中使用它:

this.unsubscribeAccount = this.props.onAccountChange();

【讨论】:

  • 啊,我明白了,所以问题在于没有返回实际的 Firebase 侦听器附件
【解决方案2】:

为了使组件被附加到存储以用于调度操作或映射道具,它与connect(mapStateToProps, mapDispatchToProps)(Component) 一起使用。在你的情况下,没有传递给组件的道具,所以我只发送nullmapStateToProps

(假设您在某个父组件 REDUX. I cant understand how to connect a component defined as a class extending React.Component in order to read the store 中使用了 Provider


 import { connect } from 'react-redux';

 class DrawerContentComponent extends React.Component {
    ...rest code...
   componentDidMount() {
     this.unsubscribeAgenda = this.props.getAgenda();
    }
   componentWillUnmount() {
    this.unsubscribeAgenda();
    }
   }
  export default connect(null, { getAgenda })(DrawerContentComponent)

【讨论】:

  • loadSuccess() 是做什么用的?因为错误来自那里......无论如何,你不能直接从'redux'而不是'react-redux'导入UI端的东西,如果你想导入dispatch而不是正常的redux流程从你的商店导入它
猜你喜欢
  • 2019-11-22
  • 2022-06-16
  • 2019-09-27
  • 1970-01-01
  • 1970-01-01
  • 2018-12-29
  • 1970-01-01
  • 1970-01-01
  • 2021-10-07
相关资源
最近更新 更多