React中触发组件内事件时切换组件的实现方案
实现React加密关卡的递进展示
要实现答对一关自动切换到下一关的效果,核心是把关卡状态提升到父组件Cryptography,让子组件在验证正确时通知父组件切换状态,具体步骤如下:
1. 调整父组件的状态与渲染逻辑
在Cryptography组件中,将原来的active状态替换为代表关卡的currentLevel,初始值设为1,再根据这个值渲染对应关卡组件:
const Cryptography = () => { // 用数字标记当前关卡,1=第一关,2=第二关,3=第三关 const [currentLevel, setCurrentLevel] = useState(1); // 切换到下一关的逻辑函数 const goToNextLevel = () => { setCurrentLevel(prev => prev + 1); }; return ( <div className="cryptography"> <h1>Cryptography</h1> <DisplayTimer /> <div className="crypto-container"> {/* 根据当前关卡渲染对应组件,同时传递切换回调 */} {currentLevel === 1 && <CryptoOne onCorrect={goToNextLevel} />} {currentLevel === 2 && <CryptoTwo onCorrect={goToNextLevel} />} {currentLevel === 3 && <CryptoThree />} </div> </div> ) }
2. 修改子组件,添加回调触发逻辑
给CryptoOne和CryptoTwo组件添加onCorrect属性,在验证答案正确时调用这个回调函数,通知父组件切换关卡:
修改CryptoOne组件
const CryptoOne = ({ onCorrect }) => { // 接收父组件传递的回调 const inputRef = useRef(); function verifyAnswer() { if (inputRef.current.value === "c6e24b99a8054ab24dd0323530b80819") { alert("Correct!"); onCorrect(); // 触发关卡切换 } else { alert("Wrong!"); } } // 返回部分保持不变,省略重复代码 }
修改CryptoTwo组件
const CryptoTwo = ({ onCorrect }) => { // 接收父组件传递的回调 const inputRef = useRef(); function verifyAnswer() { if (inputRef.current.value === "IaMaHackerManHaHa") { alert("Correct!"); onCorrect(); // 触发关卡切换 } else { alert("Wrong!"); } } // 返回部分保持不变,省略重复代码 }
3. 完整修改后的代码
整合所有修改后的完整代码如下:
import './cryptography.css'; import {useRef, useState} from 'react'; import useInterval from 'react-useinterval'; const DisplayTimer = () => { const [time, setTime] = useState(0); useInterval(() => { setTime(time + 1); }, 1000); const hours = Math.floor(time / 3600); const minutes = Math.floor((time % 3600) / 60); const seconds = time % 60; return ( <div className="timer"> <h3>Timer</h3> <p>{hours.toString().padStart(2, '0')}:{minutes.toString().padStart(2, '0')}:{seconds.toString().padStart(2, '0')}</p> </div> ) } const CryptoOne = ({ onCorrect }) => { const inputRef = useRef(); function verifyAnswer() { if (inputRef.current.value === "c6e24b99a8054ab24dd0323530b80819") { alert("Correct!"); onCorrect(); } else { alert("Wrong!"); } } return ( <div className="crypto-one"> <h3>Level One</h3> <p>Convert this plaintext into an MD5 hash - "RollingStonesGatherNoMoss"</p> <input ref={inputRef} type="text" id="one-answer" name="one-answer" /> <button onClick={verifyAnswer}>Submit</button> </div> ) } const CryptoTwo = ({ onCorrect }) => { const inputRef = useRef(); function verifyAnswer() { if (inputRef.current.value === "IaMaHackerManHaHa") { alert("Correct!"); onCorrect(); } else { alert("Wrong!"); } } return ( <div className="crypto-two"> <h3>Level Two</h3> <p>Decode Caesar cipher into plaintext - "FxJxExzhboJxkExEx"</p> <input ref={inputRef} type="text" id="two-answer" name="two-answer" /> <button onClick={verifyAnswer}>Submit</button> </div> ) } const CryptoThree = () => { const inputRef = useRef(); function verifyAnswer() { let input = inputRef.current.value; let answer = "SHA256".toLowerCase(); if (input === answer) { alert("Correct!, completed the exercise"); } else { alert("Wrong!"); } } return ( <div className="crypto-three"> <h3>Level Three</h3> <p>Identify the type of the hash (Type only the hash type, with no spaces) - "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855"</p> <input ref={inputRef} type="text" id="three-answer" name="three-answer" /> <button onClick={verifyAnswer}>Submit</button> </div> ) } const Cryptography = () => { const [currentLevel, setCurrentLevel] = useState(1); const goToNextLevel = () => { setCurrentLevel(prev => prev + 1); }; return ( <div className="cryptography"> <h1>Cryptography</h1> <DisplayTimer /> <div className="crypto-container"> {currentLevel === 1 && <CryptoOne onCorrect={goToNextLevel} />} {currentLevel === 2 && <CryptoTwo onCorrect={goToNextLevel} />} {currentLevel === 3 && <CryptoThree />} </div> </div> ) } export { Cryptography };
核心逻辑说明
- 状态提升:把控制关卡切换的状态放在父组件,让父组件统一管理所有关卡的展示逻辑。
- 回调函数:子组件通过接收父组件传递的
onCorrect回调,在验证正确时触发父组件的状态更新,实现关卡切换。 - 条件渲染:根据
currentLevel的值,只渲染当前对应的关卡组件,达到替换展示的效果。
内容的提问来源于stack exchange,提问作者ar0matix
相关产品推荐
相关产品推荐

