You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.04 11:24:05