我怎样才能更好地有条件地渲染我的组件?
Posted
技术标签:
【中文标题】我怎样才能更好地有条件地渲染我的组件?【英文标题】:How can I better conditionally render my components? 【发布时间】:2022-01-12 05:25:58 【问题描述】:我有很多组件根据我用于游戏的不同状态进行渲染。我目前正在使用用 & 号检查状态值的方法。我不确定是否应该采用其他方式,或者是否有更有效的清洁方式。
我已经查找了几种不同的方法,但想知道是否有人可以给我一些建议,让我可以很好地与我现有的代码一起工作。
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;
【问题讨论】:
你可以使用三元运算符来解决一些简单的情况 【参考方案1】:你可以尝试两件事:
首先,您有很多 boolean
状态 - 例如。 gameStarted
,其中很多似乎与 other 布尔状态互斥,例如 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>)
【讨论】:
所以我正在尝试这个,它在渲染新组件时调用我的 setgamestate 函数。例如case RANDOM_GAME_SELECTED: return <CreateRandomGame rollPlayers=rollPlayers startPlayer=startPlayer endPlayer=endPlayer startTheGame=changeGameState goBack=changeGameState />;
它渲染这段代码,然后为startTheGame
和goBack
调用changeGameState
,因为当我记录它时,它会以不同的状态运行该函数三次。
我想通了,它们是 onclick 函数,我需要做 onClick=() => goBack("GAME_CHOICE")
它必须有带箭头函数的括号以上是关于我怎样才能更好地有条件地渲染我的组件?的主要内容,如果未能解决你的问题,请参考以下文章