我怎样才能更好地有条件地渲染我的组件?
How can I better conditionally render my components?
我有很多组件根据我用于游戏的不同状态进行渲染。我目前正在使用用&符号检查状态值的方法。我不确定我是否应该采用不同的方式,或者是否有更有效、更清洁的方式。
我已经查找了几种不同的方法,但想知道是否有人可以给我一些建议,让我可以很好地配合我现有的代码。
const App = () => {
const [startPlayer, setStartPlayer] = useState("");
const [endPlayer, setEndPlayer] = useState("");
const [gameSelected, setGameSelected] = useState(false);
const [gameStarted, setGameStarted] = useState(false);
const [gameWon, setGameWon] = useState(false);
const [winningTeam, setWinningTeam] = useState([]);
const [gameSolved, setGameSolved] = useState(false);
const isMobile = useMobileCheck();
const resetGame = () => {
setStartPlayer("");
setEndPlayer("");
setGameSelected(false);
setGameStarted(false);
setGameWon(false);
setGameSolved(false);
setWinningTeam([]);
};
const setGameType = (gameType) => {
setGameSelected(gameType);
};
const rollPlayers = (startYear, endYear) => {
axios.get(`/api/gettwoplayers?startYear=${startYear}&endYear=${endYear}`).then((res) => {
setStartPlayer(res.data[0]);
setEndPlayer(res.data[1]);
});
};
const startTheGame = () => {
setGameStarted(true);
};
const goBackToGameSelection = () => {
setGameSelected(false);
setGameStarted(false);
setStartPlayer("");
setEndPlayer("");
};
const userSetPlayer = (player, type) => {
if(type === "start") setStartPlayer(player);
if(type === "end") setEndPlayer(player);
};
const theGameWasWon = (history) => {
history.push(endPlayer);
setWinningTeam(history);
setGameWon(true);
};
const solveGame = () => {
setGameSolved(true);
axios.get(`/api/solve?startPlayer=${startPlayer}&endPlayer=${endPlayer}`).then((res) => {
console.log(res.data);
})
};
return (
<Container
sx={{
minHeight:'100vh',
maxWidth: "90vw!important",
}}
>
{
!gameSelected &&
!gameStarted &&
!gameWon &&
<ChooseGame setGameType={setGameType} />
}
{
!gameStarted &&
!gameWon &&
gameSelected === 'r' &&
<CreateRandomGame
rollPlayers={rollPlayers}
startPlayer={startPlayer}
endPlayer={endPlayer}
startTheGame={startTheGame}
goBack={goBackToGameSelection}
/>
}
{
!gameStarted &&
!gameWon &&
gameSelected === 's' &&
<CreateUserGame
startPlayer={startPlayer}
endPlayer={endPlayer}
userSetPlayer={userSetPlayer}
startTheGame={startTheGame}
goBack={goBackToGameSelection}
/>
}
{
!gameWon &&
gameStarted &&
<GameScreen
startPlayer={startPlayer}
endPlayer={endPlayer}
gameWon={theGameWasWon}
resetGame={resetGame}
solveGame={solveGame}
/>
}
{
gameWon &&
<GameWon
resetGame={resetGame}
winningTeam={winningTeam}
/>
}
</Container>
);
}
export default App;
您可以尝试两件事:
首先,您有很多 boolean
状态 - 例如gameStarted
,而且很多好像和其他布尔状态互斥,比如gameStarted
看起来像吧永远不能 true
与 gameWon
同时出现。在这种情况下,将状态建模为枚举类型会好得多;不幸的是 Javascript 本身没有它们(查看 TypeScript 以获取“真实” enum
类型)但我们可以使用字符串:
const MODE_STARTED = 'started'
const MODE_SELECTED_RANDOM = 'random'
const MODE_SELECTED_USER = 'user'
const MODE_GAME_WON = 'won'
...
const [gameMode, setGameMode] = useState(MODE_STARTED);
...
现在,您无需到处翻转单个布尔值,只需更改您的游戏模式...例如setGameMode(MODE_SELECTED_RANDOM)
完成后,您的 JSX 也可以变得更干净:
const showCorrectUI = () => {
switch (gameMode) {
case MODE_STARTED:
return <GameScreen {foo} />
case MODE_GAME_WON:
return <GameWon {bar} />
... // etc
}
}
return (
<Container
sx={{
minHeight:'100vh',
maxWidth: "90vw!important",
}}
>
{showCorrectUI()}
</Container>)
我有很多组件根据我用于游戏的不同状态进行渲染。我目前正在使用用&符号检查状态值的方法。我不确定我是否应该采用不同的方式,或者是否有更有效、更清洁的方式。
我已经查找了几种不同的方法,但想知道是否有人可以给我一些建议,让我可以很好地配合我现有的代码。
const App = () => {
const [startPlayer, setStartPlayer] = useState("");
const [endPlayer, setEndPlayer] = useState("");
const [gameSelected, setGameSelected] = useState(false);
const [gameStarted, setGameStarted] = useState(false);
const [gameWon, setGameWon] = useState(false);
const [winningTeam, setWinningTeam] = useState([]);
const [gameSolved, setGameSolved] = useState(false);
const isMobile = useMobileCheck();
const resetGame = () => {
setStartPlayer("");
setEndPlayer("");
setGameSelected(false);
setGameStarted(false);
setGameWon(false);
setGameSolved(false);
setWinningTeam([]);
};
const setGameType = (gameType) => {
setGameSelected(gameType);
};
const rollPlayers = (startYear, endYear) => {
axios.get(`/api/gettwoplayers?startYear=${startYear}&endYear=${endYear}`).then((res) => {
setStartPlayer(res.data[0]);
setEndPlayer(res.data[1]);
});
};
const startTheGame = () => {
setGameStarted(true);
};
const goBackToGameSelection = () => {
setGameSelected(false);
setGameStarted(false);
setStartPlayer("");
setEndPlayer("");
};
const userSetPlayer = (player, type) => {
if(type === "start") setStartPlayer(player);
if(type === "end") setEndPlayer(player);
};
const theGameWasWon = (history) => {
history.push(endPlayer);
setWinningTeam(history);
setGameWon(true);
};
const solveGame = () => {
setGameSolved(true);
axios.get(`/api/solve?startPlayer=${startPlayer}&endPlayer=${endPlayer}`).then((res) => {
console.log(res.data);
})
};
return (
<Container
sx={{
minHeight:'100vh',
maxWidth: "90vw!important",
}}
>
{
!gameSelected &&
!gameStarted &&
!gameWon &&
<ChooseGame setGameType={setGameType} />
}
{
!gameStarted &&
!gameWon &&
gameSelected === 'r' &&
<CreateRandomGame
rollPlayers={rollPlayers}
startPlayer={startPlayer}
endPlayer={endPlayer}
startTheGame={startTheGame}
goBack={goBackToGameSelection}
/>
}
{
!gameStarted &&
!gameWon &&
gameSelected === 's' &&
<CreateUserGame
startPlayer={startPlayer}
endPlayer={endPlayer}
userSetPlayer={userSetPlayer}
startTheGame={startTheGame}
goBack={goBackToGameSelection}
/>
}
{
!gameWon &&
gameStarted &&
<GameScreen
startPlayer={startPlayer}
endPlayer={endPlayer}
gameWon={theGameWasWon}
resetGame={resetGame}
solveGame={solveGame}
/>
}
{
gameWon &&
<GameWon
resetGame={resetGame}
winningTeam={winningTeam}
/>
}
</Container>
);
}
export default App;
您可以尝试两件事:
首先,您有很多 boolean
状态 - 例如gameStarted
,而且很多好像和其他布尔状态互斥,比如gameStarted
看起来像吧永远不能 true
与 gameWon
同时出现。在这种情况下,将状态建模为枚举类型会好得多;不幸的是 Javascript 本身没有它们(查看 TypeScript 以获取“真实” enum
类型)但我们可以使用字符串:
const MODE_STARTED = 'started'
const MODE_SELECTED_RANDOM = 'random'
const MODE_SELECTED_USER = 'user'
const MODE_GAME_WON = 'won'
...
const [gameMode, setGameMode] = useState(MODE_STARTED);
...
现在,您无需到处翻转单个布尔值,只需更改您的游戏模式...例如setGameMode(MODE_SELECTED_RANDOM)
完成后,您的 JSX 也可以变得更干净:
const showCorrectUI = () => {
switch (gameMode) {
case MODE_STARTED:
return <GameScreen {foo} />
case MODE_GAME_WON:
return <GameWon {bar} />
... // etc
}
}
return (
<Container
sx={{
minHeight:'100vh',
maxWidth: "90vw!important",
}}
>
{showCorrectUI()}
</Container>)