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
相关产品推荐
相关产品推荐

