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

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.25 23:36:20