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

React Redux中useDispatch钩子配置错误排查:状态无更新

React-Redux页面不更新问题排查

我刚开始学习React结合Redux开发,若问题只是简单语法错误还请见谅。本项目要求使用多种react-redux函数。运行代码后页面内容无任何更新,推测是useDispatch钩子的使用存在错误,希望排查出问题所在。

切片代码

/** @type {{balance: number, history: Transaction[]}} */
const initialState = {balance: 0, history: []};

/* TODO
Add two reducers  to the transactions slice: "deposit" and "transfer".
Both reducers update the balance and then record the transaction.

"deposit" should increase the balance by the amount in the payload,
while "transfer" should decrease the balance by the amount in the payload.

Refer to the "withdrawal" reducer, which is already implemented for you.
*/

const transactionsSlice = createSlice({
  name: "transactions",
  initialState,
  reducers: {
    withdrawal: (state, { payload }) => {
      state.balance -= payload.amount;
      state.history.push({
        type: "withdrawal",
        amount: payload.amount,
        balance: state.balance,
      });
    },
    deposit: (state, { payload }) => {
      state.balance += payload.amount;
      state.history.push({
        type: "deposit",
        amount: payload.amount,
        balance: state.balance,
      });
    },
    transfer: (state, { payload }) => {
      state.balance -= payload.amount;
      state.history.push({
        type: "transfer",
        amount: payload.amount,
        balance: state.balance,
      });
    },
  },
});

export const { deposit, withdrawal, transfer } = transactionsSlice.actions;

export const selectBalance = (state) => state.transactions.balance;
export const selectHistory = (state) => state.transactions.history;

export default transactionsSlice.reducer;

Store配置

import { configureStore } from "@reduxjs/toolkit";
import transactionsSlice from "../features/transactions/transactionsSlice";

// TODO: Configure the store to use the reducer from the transactions slice.
export const store = configureStore({
    reducer:{
        transactions:transactionsSlice,
    }
});

Transactions组件代码

import { useState } from "react";
import { useSelector } from "react-redux";
import { useDispatch } from "react-redux";

import "./transactions.scss";

/**
 * Allows users to deposit to, withdraw from, and transfer money from their account.
 */
export default function Transactions() {
  // TODO: Get the balance from the Redux store using the useSelector hook
  const balance = useSelector(state => state.transactions.balance);
  

  const [amountStr, setAmountStr] = useState("0.00");

  const dispatch = useDispatch()

  /** Dispatches a transaction action based on the form submission. */
  const onTransaction = (e) => {
    e.preventDefault();

    // This changes depending on which button the user clicked to submit the form.
    // It will be either "deposit", "withdraw", or "transfer".
    const action = e.nativeEvent.submitter.name;

    const amount = +amountStr;

    
    dispatch({type: action, amount: amount});
    // TODO: Dispatch the appropriate transaction action based on `action`
  };

  return (
    <section className="transactions container">
      <h2>Transactions</h2>
      <figure>
        <figcaption>Current Balance &nbsp;</figcaption>
        <strong>${balance.toFixed(2)}</strong>
      </figure>
      <form onSubmit={onTransaction}>
        <div className="form-row">
          <label>
            Amount
            <input
              type="number"
              inputMode="decimal"
              min={0}
              step="0.01"
              value={amountStr}
              onChange={(e) => setAmountStr(e.target.value)}
            />
          </label>
          <div>
            <button default name="deposit">
              Deposit
            </button>
            <button name="withdraw">Withdraw</button>
          </div>
        </div>
        <div className="form-row">
          <label>
            Transfer to
            <input type="text" placeholder="Recipient Name" name="recipient" />
          </label>
          <button name="transfer">Transfer</button>
        </div>
      </form>
    </section>
  );
}

问题根源与解决方案

核心错误

你直接dispatch了自定义的action对象:dispatch({type: action, amount: amount}),但Redux Toolkit的createSlice生成的action类型是带slice名称前缀的(比如transactions/deposit),和你传入的纯deposit类型不匹配,导致reducer无法触发,状态无法更新,页面也就没有变化。另外,Withdraw按钮的name是withdraw,但切片导出的action creator是withdrawal,这里也存在名称不匹配的问题。

修复步骤

  1. 导入action creator:在Transactions组件顶部导入切片生成的action:
import { deposit, withdrawal, transfer } from '../features/transactions/transactionsSlice';

(注意路径要和你的项目结构一致)

  1. 修改dispatch逻辑:根据表单提交的action类型,调用对应的action creator:
const onTransaction = (e) => {
  e.preventDefault();
  const action = e.nativeEvent.submitter.name;
  const amount = +amountStr;

  // 根据按钮名称分发对应action
  switch(action) {
    case 'deposit':
      dispatch(deposit({ amount }));
      break;
    case 'withdraw':
      // 按钮name是withdraw,对应action creator是withdrawal
      dispatch(withdrawal({ amount }));
      break;
    case 'transfer':
      dispatch(transfer({ amount }));
      break;
    default:
      console.warn('未知操作类型');
  }
};
  1. 检查Provider是否配置:确保你的根组件已经用Provider包裹,让所有组件能访问Redux store:
import { Provider } from 'react-redux';
import { store } from './path-to-your-store-file';
import App from './App';

ReactDOM.render(
  <Provider store={store}>
    <App />
  </Provider>,
  document.getElementById('root')
);

完成以上修改后,dispatch的action就能正确匹配reducer,状态更新后页面也会随之刷新。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.24 00:25:54