基于全局状态显示零部件的提示



我正在构建具有以下用户流的游戏界面:

用户登陆其中一个游戏URL,例如www.name.com/game1,首先进入介绍屏幕,然后进入游戏屏幕,最后进入失败或成功屏幕。

我正试图找出做这件事的最佳方式。Bellow是一个运行良好的代码,但我正在寻找更优雅和可扩展的解决方案。知道吗?

import { useParams } from "react-router-dom";
import { useSelector } from "react-redux";
// Import views and components
import Step1 from "../Intro/Step1";
import StatusBar from "../../components/StatusBar/StatusBar";
import Game1 from "./Games/Game1/Game1";
import Game2 from "./Games/Game2/Game2";
import Intro from "./Intro/Intro";
import Password from "./Password/Password";
import Success from "./Success/Success";
import Fail from "./Fail/Fail";
import FailBeginOnStart from "./Fail/FailBeginOnStart";
// Data
function Game() {
const data = {
game1: {
desc: "some description for game 1",
},
game2: {
desc: "some description for game 2",
},
};
// Get global states from redux toolkit
const showIntro = useSelector((state) => state.game.showIntro);
const showSuccess = useSelector((state) => state.game.showSuccess);
const showFail = useSelector((state) => state.game.showFail);
const showPassword = useSelector((state) => state.game.showPassword);
const completedGame = useSelector((state) => state.game.completedGame);
const selectedLanguage = useSelector((state) => state.game.selectedLanguage);
// Get current param from URL (example /game1)
const { game } = useParams();
// Strip slash to get matching game ID (example game1)
const gameId = game.replace(/-/g, "");
const GameScreen = () => {
// show intro screen
if (showIntro === true) {
return (
<>
<StatusBar />
<Intro path={game} id={gameId} data={data[gameId]} />
</>
);
}
// show success screen
if (showSuccess === true) {
return (
<>
<StatusBar />
<Success data={data[gameId]} />
</>
);
}
// show fail screen
if (showFail === true) {
return (
<>
<StatusBar />
<Fail data={data[gameId]} />
</>
);
}
// Show actual game
switch (true) {
case game === "game1":
return <Game1 data={data[gameId]} />;
case game === "game2":
return <Game2 data={data[gameId]} />;
default:
return <Step1 />;
}
};
return <GameScreen />;
}
export default Game;

我建议您使用React Router并更改为基于类的组件。你可以做一个BaseGame类作为具体游戏的模板。(如果你使用的是typescript,你可以把它变成一个抽象类。(.

这些示例没有关于页面实际流程的进一步信息,因此您可能需要对其进行调整

class BaseGame extends React.Component {
// creating dummy members that get overwritten in concrete game classes
desc = "";
id = 0;
data = {}
constructor(){
this.state={
intro: true,
success: false,
fail: false
}
}
/** just dummy functions as we don't have access to
/*  abstract methods in regular javascript.
/*
*/
statusBar(){ return <div>Statusbar</div>}
gameScreen(){ return <div>the Game Screen</div>}

render(){
return (
{this.statusBar()}
{if(this.state.intro) <Intro data={this.data} onStart={() => this.setState({intro: false})}/>}
{if(this.state.success) <Success data={this.data}/>}
{if(this.state.fail) <Faildata={this.data}/>}
{if(!this.state.intro && !this.state.fail && !this.state.success) this.gameScreen()} 
)
}
}
class Game1 extends BaseGame {
id = 1;
data = {GameData}
// actual implementation of the screens
statusBar(){ return <div>Game1 StatusBar</div>}
gameScreen(){ return (
<div>
<h1>The UI of Game 1</h1>
Make sure to setState success or failure at the end of the game loop
</div>
)}
}

和在你的应用程序功能

const App = () => (
<Router>
<Switch>
<Route exact path="/" component={Step1} />
<Route path="/game1" component={Game1} />
<Route path="/game2" component={Game2} />
...
</Switch>
</Router>
)

只是一个快速的想法。你可能想添加一个像Redux这样的集中式商店,这取决于你想在哪里管理State。但当不同的游戏类不需要共享状态时,它们可以很好地自行管理。还取决于状态栏的作用,它可以在游戏之外,也可以只在你的应用程序功能中

...
<StatusBar />
<Router>
... etc.
</Router>

在您的应用程序功能中。

最新更新