如何修复 react 本机项目中"dispatch is not a function"错误



在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()(中创建的函数来实现这一点,而不必重写组件中的代码,因为我目前这样做只是为了能够在卸载时取消订阅侦听器,这是我想让它工作的唯一方法。

理想情况下,我想做这样的事情:

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

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

有什么应对策略?

您不能直接从redux导入调度。

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

如果你正在使用一个功能组件,你可以使用useDispatch来访问它

如果你不想使用普通的react redux选项,你可以从你的商店导出调度,然后从你创建商店的地方导入。

export const dispatch = store.dispatch

如果firestore的大部分逻辑都在redux-thunk操作中(或类似的异步功能(,请使用connect将操作封装在dispatch中,并在最后按照理想状态运行它。无论你从thunk操作返回什么,都会从调用中返回,所以你应该能够将其设置为返回unsubscribe函数。

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

然后,您可以使用调度onAccountChange操作创建者

this.props.onAccountChange()

编辑:

将你的onAccountChange函数修改为这样,这样你的thunk就会返回你的unsucibe函数。

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-to-props中,并在componentDidMount方法中使用它:

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

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

(假设您在某个父组件REDUX中使用了Provider。我不明白如何连接定义为扩展React.component类的组件以读取存储(


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)

最新更新