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

TypeScript React中用useReducer实现点击按钮递增指定属性值

解决React useReducer属性递增的类型错误与渲染问题

问题1:({[key]: value + 1})中value类型unknown

这是因为TypeScript无法推断动态key对应的state值类型,你需要先约束key的合法范围,确保它只能是你定义的属性名。

首先定义属性类型和状态类型:

// 限定合法的属性键
type AttributeKey = 'STR' | 'AGI' | 'INT' | 'CHA';
// 状态类型:每个属性对应一个数值
type AttributesState = Record<AttributeKey, number>;

然后在reducer里,给action的key加上类型约束,这样TypeScript就能确定state[action.key]是number类型:

type Action = {
  type: 'inc_Attributes';
  key: AttributeKey; // 明确key的类型
};

const attributesReducer = (state: AttributesState, action: Action): AttributesState => {
  switch (action.type) {
    case 'inc_Attributes':
      // 这里state[action.key]的类型会被正确推断为number,不会再提示unknown
      return {
        ...state,
        [action.key]: state[action.key] + 1
      };
    default:
      return state;
  }
};

问题2:“Objects are not valid as a React child”错误

这个错误几乎都是因为你在JSX里直接渲染了对象而非原始值(字符串、数字等)。检查你的渲染代码:

  • 不要直接写{state},这会把整个状态对象当成React子元素,应该渲染具体属性值,比如{state.STR}。
  • 确保按钮点击时传递的dispatch参数正确,不要把对象误传给子组件或渲染逻辑。

举个正确的渲染示例:

export default function Attributes() {
  const initialState: AttributesState = { STR: 10, AGI: 10, INT: 10, CHA: 10 };
  const [state, dispatch] = useReducer(attributesReducer, initialState);

  const handleIncrement = (key: AttributeKey) => {
    dispatch({ type: 'inc_Attributes', key });
  };

  return (
    <div>
      {Object.entries(state).map(([key, value]) => (
        <div key={key}>
          {/* 渲染具体的属性名和数值,而非整个对象 */}
          <span>{key}: {value}</span>
          {/* 点击时传递正确的属性键 */}
          <button onClick={() => handleIncrement(key as AttributeKey)}>+</button>
        </div>
      ))}
    </div>
  );
}

关键注意点

  • 始终给动态key做类型约束,避免TypeScript类型推断失效。
  • JSX中只能渲染React允许的子元素类型(字符串、数字、React元素等),绝对不能直接渲染对象或数组(除非你先处理成可渲染的内容)。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.04 14:21:03