Redux中调用store.dispatch无法更新状态但useDispatch正常是什么原因?
问题描述
我开发的组件仅包含加减按钮,使用react-redux提供的useDispatch派发action时可以正常更新Redux状态,但直接调用store.dispatch()方法时状态没有触发更新,以下是对应的组件代码:
import React from 'react'; import { SafeAreaView } from 'react-native'; import moment from 'moment'; import { FlatList, Text, View, Button } from 'react-native'; import { Card, Paragraph, Divider } from 'react-native-paper'; import { useSelector, useDispatch } from 'react-redux'; import AppContainer from '../Common/AppContainer'; import LinearButton from '../Common/Button'; import translation from '../../Util/Translation'; import styles from '../../Components/Styles/Notification/Notification'; import NotificationAction from '../../Redux/Notification/Actions'; import createStore from '../../Redux/CreateStore'; const { t } = translation; const NotificationScreen = (props) => { const { NotificationDetails, onSendNotificationPress } = { ...props }; const count = useSelector((state) => state.notificationReducer); const { store } = createStore(); const dispatch = useDispatch(); const addPress = () => { store.dispatch(NotificationAction.add(23)); }; return ( <SafeAreaView style={styles.container}> <AppContainer title={t('NOTIFICATION')} leftIcon="ios-arrow-back" isLeft> <FlatList data={NotificationDetails.sort((_val, $val) => new Date($val.data) - new Date(_val.data))} keyExtractor={(item, i) => i.toString()} showsVerticalScrollIndicator={false} ItemSeparatorComponent={() => <Divider />} renderItem={({ item }) => { return ( <View style={styles.fltLst}> <View style={styles.flt}> <View style={styles.drtn}> <Text style={styles.hdr}>Notification</Text> <Paragraph> {moment(item.data).startOf().fromNow()}</Paragraph> </View> <Text>{item.Subscriber_Status}</Text> </View> </View> ); }} /> </AppContainer> <View style={styles.buttonView}> <View style={styles.button}> <LinearButton title={t('SENDNOTIFICATION')} onPress={onSendNotificationPress} /> </View> <Button title="Add" onPress={addPress} /> <Text style={[styles.hdr, { alignSelf: 'center' }]}> {count}</Text> <Button title="Remove" /> </View> </SafeAreaView> ); }; export default NotificationScreen;
根因分析
你在组件内部通过const { store } = createStore()生成了全新的store实例,和应用根节点<Provider>组件绑定的全局唯一store不是同一个对象。你调用这个孤立store实例的dispatch方法,只会修改它自身维护的状态,不会触发Provider关联状态的更新,因此useSelector无法监听到状态变化。
解决方案
- 首先删除组件内的
const { store } = createStore();代码行:Redux的store在普通单页应用中是全局单例,只需要在应用初始化时调用一次createStore生成实例,传入根<Provider>即可,不需要在业务组件中重复初始化。 - 你当前的场景是在React组件内部派发action,直接使用已经通过
useDispatch生成的dispatch实例即可,修改addPress方法如下:
const addPress = () => { dispatch(NotificationAction.add(23)); };
- 如果确实有在非React组件场景下直接调用
store.dispatch的需求,可以在你定义createStore的入口文件导出初始化完成的单例store,业务代码直接导入该实例即可,不要重复执行createStore生成新实例。
注意事项
重复调用createStore生成多个store实例是Redux使用的常见新手错误,只有多实例状态隔离、服务端渲染等特殊场景才需要多次调用该方法,普通业务场景全局仅需维护一个store实例即可。
内容的提问来源于stack exchange,提问作者AsZik
相关产品推荐
相关产品推荐

