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

React组件使用Redux不更新问题排查

问题:React中使用原生Redux无法更新App组件

我正在学习Redux,用React搭建一个简单项目,期望点击按钮后段落中能渲染对应文本,但唯一的App组件无法更新。想知道问题出在哪?

附上代码:

import { createStore } from 'redux'

const deleteUsers = 'delete users';

const createUser = 'créate user';

const createUserStranger = 'create stranger';

function deleteUsersActionCreator() {
  return {
    type: deleteUsers,
    data: []
  }
}

function createUsersActionCreator() {
  return {
    type: createUser,
    data: ['Irina', 'Denis', 'Julio']
  }
}

function createUserStrangerActionCreator() {
  return {
    type: createUserStranger,
    data: 'stranger'
  }
}

const initialState = {
  users: []
}

const reducer = (state = initialState, action) => {
  switch (action.type) {
    case createUser:
      return {
        ...state,
        users: [...state.users, ...action.data]

      }
    case deleteUsers:
      return {
        ...state,
        users: []
      }
    case createUserStranger:
      return {
        ...state,
        users: [...state.users, action.data]
      }
      default:
        return state
  }
};

function dispatchAction(action) {
  store.dispatch(action)
}
const store = createStore(reducer);

let users = [];
store.subscribe(() => {
  users = store.getState().users
  console.log('users', users)

});


const App = () => {
  console.log(store.getState().users.map(e => e));
  console.log('rendering again')

  return (
    <div className="App">
      <h1>People App </h1>
      <hr/>
      <p>
      {
        store.getState().users.map( user => {
          return 
          (<p>{user}</p>)
        })
      }
      </p>
      <button onClick={()=> dispatchAction(createUsersActionCreator())}>Add Family</button>
      <button onClick={()=> dispatchAction(createUserStrangerActionCreator())}>Add Stranger</button>
      <button onClick={()=> dispatchAction(deleteUsersActionCreator())}>Delete users</button>
    </div>
  )
}

export default App

我知道应该使用useState、useEffect等方案,但作为React零基础学习者,我想先掌握原生Redux,也了解过Zustand之后会学习,欢迎给出建议。


问题分析与修复方案

1. 组件不更新的核心原因

React组件只有在自身state变化或props更新时才会触发重新渲染。你虽然通过store.subscribe监听了store变化,但只是更新了一个普通变量users,这个变量和App组件没有任何绑定关系,组件完全不知道store已经改变,所以不会重新渲染。

2. 列表渲染的语法错误

你的map方法里存在自动分号插入的问题:

store.getState().users.map( user => {
  return 
  (<p>{user}</p>)
})

JavaScript会在return语句后自动插入分号,相当于return;,后面的JSX代码不会被执行,最终map返回的是一堆undefined,所以即使组件渲染了,也看不到用户列表。


修复步骤

步骤1:让组件响应store变化

在App组件内部,用React的状态作为触发器,结合store.subscribe强制组件在store变化时重新渲染:

import { useState, useEffect } from 'react'; // 先导入useState和useEffect

const App = () => {
  // 用一个空对象作为状态,每次更新它来触发渲染
  const [, forceRender] = useState({});

  useEffect(() => {
    // 订阅store变化,每次变化时更新状态触发渲染
    const unsubscribe = store.subscribe(() => {
      forceRender({});
    });
    // 组件卸载时取消订阅,避免内存泄漏
    return unsubscribe;
  }, []);

  // 其他代码不变
}

步骤2:修复map的return语法问题

把return和JSX放在同一行,或者用括号包裹确保代码正确执行,同时记得给列表项加唯一的key属性(React列表渲染的要求):

{
  store.getState().users.map(user => (
    <p key={user}>{user}</p>
  ))
}

或者:

{
  store.getState().users.map(user => {
    return <p key={user}>{user}</p>;
  })
}

额外建议

  • 原生Redux的手动订阅写法在实际项目中很少用,官方推荐使用react-redux库的Provider、useSelector和useDispatch钩子,它们能更优雅地实现React与Redux的绑定,自动处理订阅和渲染触发。
  • 等你掌握了Redux核心概念(store、reducer、action、dispatch、subscribe)后,建议学习Redux Toolkit——它是官方推出的Redux简化工具,能大幅减少重复代码,比如用createSlice替代手动写reducer和action creator。
  • Zustand是轻量级状态管理库,语法更简洁,适合小型项目,等你熟悉Redux和React状态管理的核心逻辑后再学习会更容易上手。

内容的提问来源于stack exchange,提问作者Julio Rodriguez

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.11 05:10:32