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

React组件中如何为按钮传值并实现状态校验?

React实现按钮值传递与状态匹配校验方案

核心思路

先在App组件中存储当前Person的status状态,让按钮点击时传递自身文本值到校验函数,最后在校验函数中对比两者是否匹配,匹配则更新分数。

具体修改步骤

1. App组件新增状态存储当前Person的status

在App组件的状态定义部分,添加用于保存当前Person状态的变量:

const [currentPersonStatus, setCurrentPersonStatus] = useState('');

2. 调整Person组件的状态传递逻辑

原代码中Person直接调用校验函数传递status,现在改为让App组件持有状态,通过props传递状态设置函数:

  • App组件中修改Person的调用:
<Person className="Person" onSetPersonStatus={setCurrentPersonStatus}></Person>
  • Person组件中引入useEffect避免重复触发状态更新,并调用传递来的函数设置状态:
import { useEffect } from "react"; // 引入useEffect

function Person({ onSetPersonStatus }) {
  var length = data.length - 1;

  useEffect(() => {
    onSetPersonStatus(data[length].status);
  }, [onSetPersonStatus, length]); // 仅在依赖项变化时执行

  // 原有渲染逻辑保持不变
  return (
    <>
      <div>
        <img id="Photo" src={data[length].img} alt="Person portrait" />
      </div>
      <div className="Person-name">
        {capitalizeFirstLetter(data[length].name)}
      </div>
    </>
  );
}

3. 让按钮传递自身文本值到校验函数

修改App组件中按钮的onClick事件,通过箭头函数将按钮文本作为参数传入校验函数:

<Stack spacing={2} direction="row">
  <Button onClick={() => statusCheck('Dead')} variant="contained">
    Dead
  </Button>
  <Button onClick={() => statusCheck('Ugly')} variant="contained">
    Ugly
  </Button>
</Stack>

如果按钮选项较多,也可以用数组循环渲染,避免重复代码:

const buttonOptions = ['Dead', 'Ugly'];

// 渲染按钮部分替换为:
<Stack spacing={2} direction="row">
  {buttonOptions.map(option => (
    <Button key={option} onClick={() => statusCheck(option)} variant="contained">
      {option}
    </Button>
  ))}
</Stack>

4. 更新校验函数实现匹配逻辑

修改statusCheck函数,接收按钮的选择值,与当前Person的status对比,匹配则触发分数更新:

function statusCheck(selectedValue) {
  // 忽略大小写对比,可根据需求调整
  if (selectedValue.toLowerCase() === currentPersonStatus.toLowerCase()) {
    updateScore();
    console.log('匹配成功,分数+1');
  } else {
    console.log('匹配失败');
  }
}

修改后的完整代码

App组件完整代码

import Stack from "@mui/material/Stack";
import { Button } from "@mui/material";
import { useState } from "react";
import "./App.css";
import Person from "./Person";
import Feedback from "./Feedback";
import Score from "./Score";

function App() {
  const [score, setScore] = useState(0);
  const [currentPersonStatus, setCurrentPersonStatus] = useState('');

  function statusCheck(selectedValue) {
    if (selectedValue.toLowerCase() === currentPersonStatus.toLowerCase()) {
      updateScore();
      console.log('匹配成功,分数+1');
    } else {
      console.log('匹配失败');
    }
  }

  function updateScore() {
    setScore((prev) => prev + 1);
  }

  return (
    <div className="Main">
      <div className="Stats">
        <Score score={score} className="Score"></Score>
        <Feedback className="Feedback"></Feedback>
      </div>

      <Person className="Person" onSetPersonStatus={setCurrentPersonStatus}></Person>

      <div className="Buttons">
        <Stack spacing={2} direction="row">
          <Button onClick={() => statusCheck('Dead')} variant="contained">
            Dead
          </Button>
          <Button onClick={() => statusCheck('Ugly')} variant="contained">
            Ugly
          </Button>
        </Stack>
      </div>
    </div>
  );
}

export default App;

Person组件完整代码

import "./App.css";
import { useEffect } from "react";
import data from "./data.json";

function capitalizeFirstLetter(string) {
  return string.charAt(0).toUpperCase() + string.slice(1);
}

function Person({ onSetPersonStatus }) {
  var length = data.length - 1;

  useEffect(() => {
    onSetPersonStatus(data[length].status);
  }, [onSetPersonStatus, length]);

  return (
    <>
      <div>
        <img id="Photo" src={data[length].img} alt="Person portrait" />
      </div>
      <div className="Person-name">
        {capitalizeFirstLetter(data[length].name)}
      </div>
    </>
  );
}

export default Person;

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.17 02:20:37