React useReducer计算器数字不显示问题排查求助
问题排查:React useReducer计算器数字无法显示
问题场景
使用React useReducer开发计算器,数字/操作按钮已封装为独立组件,按钮可正常渲染,但点击后数字无法显示在计算器面板上,聚焦ACTIONS.ADD_DIGIT相关逻辑排查。
核心代码
App组件(含Reducer逻辑)
import React , {useReducer ,useState}from "react"; import ButtonDigit from "./ButtonDigit"; import ButtonOperation from "./ButtonOperation"; import "./style.css" export const ACTIONS = { ADD_DIGIT : 'add-digit', DELETE_DIGIT: 'delete-digit', CLEAR: 'clear', CHOOSE_OPERATION: 'choose-operation', EVALUATION: 'evaluation' } function reducer (state, action) { switch(action.type){ case ACTIONS.ADD_DIGIT: return {...state, currentOperand: `${state.currentOperand || ""}${action.payload}`} case ACTIONS.DELETE_DIGIT: return state case ACTIONS.CLEAR: return {currentOperand: 0} case ACTIONS.CHOOSE_OPERATION: return state case ACTIONS.EVALUATION: return state default: return state } } export default function App() { const [{prevOperand=null, currentOperand =0, operation=null}, dispatch] = useReducer(reducer,{}) return ( <div className="calculator-grid"> <div className="output"> <div className="prev-operand">{prevOperand} {operation}</div> <div className="current-operand">{currentOperand}</div> </div> <button className="span-two">AC</button> <button>DEL</button> <ButtonOperation operation={'/'} dispatch={dispatch}/> <ButtonDigit number="1" dispatch={dispatch}/> <ButtonDigit number="2" dispatch={dispatch}/> <ButtonDigit number="3" dispatch={dispatch}/> <ButtonOperation operation={'*'} dispatch={dispatch}/> <ButtonDigit number="4" dispatch={dispatch}/> <ButtonDigit number="5" dispatch={dispatch}/> <ButtonDigit number="6" dispatch={dispatch}/> <ButtonOperation operation={'+'} dispatch={dispatch}/> <ButtonDigit number="7" dispatch={dispatch}/> <ButtonDigit number="8" dispatch={dispatch}/> <ButtonDigit number="9" dispatch={dispatch}/> <ButtonOperation operation={'-'} dispatch={dispatch}/> <ButtonOperation operation={'.'} dispatch={dispatch}/> <ButtonDigit number="0" dispatch={dispatch}/> <button className="span-two">=</button> </div> ); }
ButtonDigit组件
import React from 'react' import ACTIONS from './App' export default function ButtonDigit({number,dispatch}) { return ( <> <button onClick={() => dispatch({type:ACTIONS.ADD_DIGIT , payload:number})}> {number} </button> </> ) }
问题根源
ACTIONS导入错误:在
ButtonDigit组件中,ACTIONS是App组件中用export const导出的具名常量,但使用了默认导入import ACTIONS from './App',导致ACTIONS实际指向App组件本身(默认导出的是App函数),而非定义的ACTIONS对象。点击按钮时dispatch的type为undefined,reducer无法匹配到ACTIONS.ADD_DIGIT分支,状态不会更新。初始state默认值不一致:useReducer初始state为
{},解构时给currentOperand设了默认值0,但第一次调用ADD_DIGIT时,reducer中的state.currentOperand是undefined,虽用|| ""处理,但初始渲染的currentOperand是0,第一次点击后会变成"01"这类字符串,不符合常规计算器的输入逻辑。
修复方案
修复ButtonDigit的ACTIONS导入
将ButtonDigit中的导入改为具名导入:
import React from 'react' // 改为具名导入匹配导出方式 import { ACTIONS } from './App' export default function ButtonDigit({number,dispatch}) { return ( <> <button onClick={() => dispatch({type:ACTIONS.ADD_DIGIT , payload:number})}> {number} </button> </> ) }
优化初始state(可选但推荐)
修改App中useReducer的初始state,统一状态默认值:
// 直接在初始state中设置默认值,避免解构和reducer中的状态不一致 const [{prevOperand, currentOperand, operation}, dispatch] = useReducer(reducer, { prevOperand: null, currentOperand: "", operation: null }) // 同时调整reducer的ADD_DIGIT分支,优化输入逻辑(避免重复输入0) case ACTIONS.ADD_DIGIT: if (action.payload === "0" && state.currentOperand === "0") return state return {...state, currentOperand: `${state.currentOperand}${action.payload}`}
验证
修复后点击数字按钮,reducer会正确匹配ADD_DIGIT类型,更新currentOperand值,计算器面板即可正常显示点击的数字。
内容的提问来源于stack exchange,提问作者K E
相关产品推荐
相关产品推荐

