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

如何在React计算器应用中将按键组件的按钮值传递到显示组件

可以通过状态提升的方案实现按键值到屏幕组件的传递,平级子组件共享的数据统一放到公共父组件App中管理即可,具体实现如下:

1 父组件App改造

将计算相关的状态和点击处理逻辑放到App组件,再透传给对应的子组件:

import * as React from "react"
import { useState } from "react" // 新增导入useState
import {
  ChakraProvider,
  Box,
  Text,
  Flex,
  Center,
  Spacer,
  Container,
  VStack,
  FormControl,
  FormLabel,
  Switch,
  useColorMode,
  useColorModeValue,
  Input,
  Grid,
  GridItem
} from "@chakra-ui/react"
import "@fontsource/spartan/700.css"
import customTheme from "./theme"
import CalculatorButton from "./button-component";
import FunctionalButton from "./function-component";

// 定义计算器状态类型
interface CalculatorData {
  currentValue: string; // 当前输入值
  prevValue: string; // 上一次输入值
  operator: string | null; // 选中的运算符
}

export default function App(){  
  // 初始化计算器状态
  const [calcData, setCalcData] = useState<CalculatorData>({
    currentValue: "0",
    prevValue: "",
    operator: null
  })

  // 按钮点击处理函数,后续算术运算逻辑也在这里实现
  const handleButtonPress = (value: number | string) => {
    // 这里可以根据value类型(数字/运算符/功能键)写对应的处理逻辑
    // 示例:点击数字直接更新当前显示值
    if(typeof value === "number") {
      setCalcData(prev => ({
        ...prev,
        currentValue: prev.currentValue === "0" ? String(value) : prev.currentValue + value
      }))
    }
    // 运算符、重置、删除、等于逻辑自行补充即可
  }

  return (
    <ChakraProvider theme={customTheme}>
    <Box bg={"bisque"} color={"white"} h="100vh">
      {/* Main App Container */}
      <Box pt="10">
        <Center>
          <VStack>
            {/* Top bar */}
            <TopBar />
            {/* Result Display 传入要显示的值 */}
            <DisplayResult displayValue={calcData.currentValue} />
            {/* Keys pad 传入点击处理函数 */}
            <KeypadButtons onButtonPress={handleButtonPress} />
          </VStack>
        </Center>
      </Box>
    </Box>
  </ChakraProvider>
  );
}
2 DisplayResult组件改造

移除内部状态,接收父组件传入的显示值:

interface DisplayResultProps {
  displayValue: string;
}

function DisplayResult({ displayValue }: DisplayResultProps) {
  return (
    <Box size="lg" mb="2" sx={{ width: "100%" }}>
    <Input
      placeholder="0"
      textAlign="right"
      p="10"
      bg={darkSaturatedBlue.screenBackgroundColor}
      border="none"
      fontSize="23"
      value={displayValue}
      readOnly // 禁止手动输入,只能通过按钮修改
       />
    </Box>
  );
}
3 KeypadButtons组件改造

接收父组件传入的点击函数,透传给每个按钮:

interface KeypadButtonsProps {
  onButtonPress: (val: number | string) => void;
}

function KeypadButtons({ onButtonPress }: KeypadButtonsProps) {
  return <Container bg={darkSaturatedBlue.toggleKeybadBackgroundColor} borderRadius="3" p="3">
    <Grid templateColumns="repeat(4,1fr)" templateRows="repeat(5,1fr)" gap="2">
      <CalculatorButton onClick={() => onButtonPress(7)} digit={7} color="white" size="md" bg={darkSaturatedBlue.buttonDigitColor} />
      <CalculatorButton onClick={() => onButtonPress(8)} digit={8} color="white" size="md" bg={darkSaturatedBlue.buttonDigitColor}/>
      <CalculatorButton onClick={() => onButtonPress(9)} digit={9} color="white" size="md" bg={darkSaturatedBlue.buttonDigitColor}/>
      <FunctionalButton onClick={() => onButtonPress("DEL")} digit={"DEL"} color="white" size="md" boxShadow="md"  />
      <CalculatorButton onClick={() => onButtonPress(4)} digit={4} color="white" size="md" bg={darkSaturatedBlue.buttonDigitColor}/>
      <CalculatorButton onClick={() => onButtonPress(5)} digit={5} color="white" size="md" bg={darkSaturatedBlue.buttonDigitColor}/>
      <CalculatorButton onClick={() => onButtonPress(6)} digit={6} color="white" size="md" bg={darkSaturatedBlue.buttonDigitColor}/>
      <FunctionalButton onClick={() => onButtonPress("+")} digit={"+"} color="white" size="md" boxShadow="md" />
      <CalculatorButton onClick={() => onButtonPress(1)} digit={1} color="white" size="md" bg={darkSaturatedBlue.buttonDigitColor}/>
      <CalculatorButton onClick={() => onButtonPress(2)} digit={2} color="white" size="md" bg={darkSaturatedBlue.buttonDigitColor}/>
      <CalculatorButton onClick={() => onButtonPress(3)} digit={3} color="white" size="md" bg={darkSaturatedBlue.buttonDigitColor}/>
      <FunctionalButton onClick={() => onButtonPress("-")} digit={"-"} color="white" size="md" boxShadow="md" />
      <FunctionalButton onClick={() => onButtonPress(".")} digit={"."} color="white" size="md" boxShadow="md" />
      <CalculatorButton onClick={() => onButtonPress(0)} digit={0} color="white" size="md" bg={darkSaturatedBlue.buttonDigitColor}/>
      <FunctionalButton onClick={() => onButtonPress("/")} digit={"/"} color="white" size="md" boxShadow="md" />
      <FunctionalButton onClick={() => onButtonPress("x")} digit={"x"} color="white" size="md"  boxShadow="md"/>
      <GridItem colSpan={2}>
        <FunctionalButton onClick={() => onButtonPress("RESET")} digit={"RESET"} color="teal" size="md" style={buttonStyle} boxShadow="md" />
      </GridItem>
      <GridItem colSpan={2}>
        <FunctionalButton onClick={() => onButtonPress("=")} digit={"="} color="red" size="md" style={buttonStyle} boxShadow="md" />
      </GridItem>
    </Grid>
  </Container>;
}
4 按钮组件改造

接收onClick参数绑定到原生按钮事件:

4.1 CalculatorButton.tsx

import * as React from 'react';
import {Button} from '@chakra-ui/react';

interface CalculatorButtonProps {
  digit:Number,
  color:string,
  bg?:string,
  size:string,
  onClick: () => void;
}

const CalculatorButton: React.FC<CalculatorButtonProps> = ({digit,color,bg,size,onClick}) => {
    return (
        <Button onClick={onClick} colorScheme="White" size={size} m="1" bg={bg} variant="solid">
            {digit}
        </Button>
    );
}

export default CalculatorButton;

4.2 FunctionalButton.tsx

import * as React from 'react';
import {Button} from '@chakra-ui/react';

interface FunctionalButtonProps {
  digit:string,
  color:string,
  boxShadow:string,
  size:string,
  style?:object,
  onClick: () => void;
}

const FunctionalButton : React.FC<FunctionalButtonProps> = ({digit,color,boxShadow,size,style,onClick}) => {
    return (
        <Button onClick={onClick} colorScheme={color} size={size} sx={style} m="1" boxShadow={boxShadow}>
            {digit}
        </Button>
    )
}

export default FunctionalButton;

后续所有的运算逻辑、重置、删除、等于计算的逻辑都可以直接在App组件的handleButtonPress函数中实现即可。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.30 18:45:03