我在 App.js“score”中创建了一个道具。它由 Gameboard.js 继承,然后到 Endscene.js。现在,当道具更新时,Gameboard.js 中的“分数”不会改变。我还将“分数”从 App.js 继承到 Header.js 并在那里正确更新。我知道它是异步工作的,并且不会直接更新。但即使我等一分钟,也没有任何改变。 Gameboard 中的分数仍然为 0。
我在 App.js 中创建了“分数”并继承到 Gameboard.js
function App() {
const [textBox, setTextBox] = useState('Welcome To The Party')
const [score, setScore] = useState(0)
return (
<div className="App">
<Header text={textBox} score={score} timer={timer} decreaseTimer={decreaseTimer} timerActive={timerActive}/>
<Gameboard
setText={setText}
increaseScore={increaseScore}
score={score}
resetScore={resetScore}
timer={timer}
toggleTimer={toggleTimer}
resetTimer={resetTimer}
/>
<Footer />
</div>
);
这里我继承到Endscript.js,这里是空的。即使我增加它。但它在 Header.js 中正常工作
function handleEndScene() {
const gameboard = document.getElementById('gameboard')
gameboard.style.backgroundImage = ('')
ReactDOM.render(
<EndScene
handleButton={handleButton}
score={props.score}
/>, gameboard
)
}
现在整个事情的有趣部分是。
useEffect(() => {
setScore(props.score);
console.log('Use Effect')
console.log(props.score)
}, [props.score])
Console.log(props.score) 具有当前值。例如,当我增加它时。但它不会更新 Gameboard.js 中的得分函数(我删除了它,因为它什么也没有)。尽管如此,console.log 运行良好。但就在那个功能
下面的完整代码
App.js
import React, {useState} from 'react';
import Header from './Components/Header'
import Footer from './Components/Footer'
import Gameboard from './Components/Gameboard';
function App() {
const [textBox, setTextBox] = useState('Welcome To The Party')
const [score, setScore] = useState(0)
const [timer, setTimer] = useState(30)
const [timerActive, setTimerActive] = useState(false)
const setText = (text) => {
setTextBox(text)
}
const increaseScore = () => {
setScore(score + 1)
}
const resetScore = () => {
setScore(0)
}
const decreaseTimer = () => {
setTimer(timer - 1)
}
const toggleTimer = () => {
setTimerActive(prevTimerActive => !prevTimerActive);
};
const resetTimer = () => {
setTimer(30)
}
return (
<div className="App">
<Header text={textBox} score={score} timer={timer} decreaseTimer={decreaseTimer} timerActive={timerActive}/>
<Gameboard
setText={setText}
increaseScore={increaseScore}
score={score}
resetScore={resetScore}
timer={timer}
toggleTimer={toggleTimer}
resetTimer={resetTimer}
/>
<Footer />
</div>
);
}
export default App;
Gamebard.js
import React, { useState, useEffect } from 'react'
import ReactDOM from 'react-dom';
import Character from './Character'
import EndScene from './EndScene'
import '../Styles/Gameboard.css'
export default function Gameboard(props) {
const [charList, setCharList] = useState([])
const [mapList, setMapList] = useState([])
const [characterAlive, setCharacterAlive] = useState([])
const [roundActive, setRoundActive] = useState(false)
// const [score, setScore] = useState(0)
useEffect(() => {
buildCharList()
buildMapList()
}, [])
// useEffect(() => {
// setScore(props.score);
// console.log('Use Effect')
// console.log(props.score)
// }, [props.score])
useEffect(() => {
if (props.timer === 0 && roundActive) handleEndScene()
}, [props.timer])
function handleEndScene() {
const gameboard = document.getElementById('gameboard')
gameboard.style.backgroundImage = ('')
ReactDOM.render(
<EndScene
handleButton={handleButton}
score={props.score}
/>, gameboard
)
}
const resetCharacterAlive = () => {
const newArray = []
setCharacterAlive(newArray)
}
function handleEndRound() {
if (characterAlive.length === charList.length) {
// Update text and score
props.setText('You Found All')
props.increaseScore()
//Update round/ reset data
setRoundActive(false)
props.toggleTimer()
// Display select buttons
const gameboard = document.getElementById('gameboard')
const buttonGroup = () => (
<>
<button onClick={handleButton} className='startGameBtn btn btn-info position-absolute'>Start Game</button>
<button onClick={handleEndScene} className='leaveGameBtn btn btn-danger position-absolute'>Leave Game</button>
</>
)
ReactDOM.render(buttonGroup(), gameboard)
}
}
function buildMapList() {
function importAll(r) {
return r.keys().map(r);
}
const images = importAll(require.context('../Assets/', true, /\.jpg/))
setMapList(images);
}
function buildCharList() {
function importAll(r) {
return r.keys().map(r);
}
const images = importAll(require.context('../Assets/', true, /\.png/))
setCharList(images);
}
function handleSetupGameboard() {
const map = mapList.slice().sort(() => Math.random() - 0.5)[0]
const gameboard = document.getElementById('gameboard')
gameboard.style.backgroundImage = `url(${map})`
const gameboardRect = gameboard.getBoundingClientRect()
const charWidth = 70
const charHeight = 70
const maxX = gameboardRect.width - charWidth
const maxY = gameboardRect.height - charHeight
const newCharList = charList.slice().sort(() => Math.random() - 0.5);
const charElements = newCharList.map((char, index) => {
const xPos = Math.floor(Math.random() * (maxX + 1))
const yPos = Math.floor(Math.random() * (maxY + 1))
return [
<Character
setText={props.setText}
src={char}
style={{
left: `${xPos}px`,
top: `${yPos - (index * charHeight)}px`,
}}
key = {index}
onClick={handleCharFound}
></Character>
];
})
ReactDOM.render(charElements, gameboard)
props.setText('Find Waldo, Lady Waldo and Wizzard')
}
function handleCharFound(event) {
if (!characterAlive.includes(event.target.src)) {
const newCharacterAlive = characterAlive
newCharacterAlive.push(event.target.src)
setCharacterAlive(newCharacterAlive);
}
// if (!characterAlive.includes(event.target.src)) {
// const newCharacterAlive = [...characterAlive, event.target.src];
// setCharacterAlive(newCharacterAlive);
// console.log(newCharacterAlive)
// }
handleEndRound()
console.log(`Char:${charList.length}, Alive:${characterAlive.length}`)
}
function handleButton() {
resetCharacterAlive()
setRoundActive(true)
handleSetupGameboard()
props.resetScore()
props.resetTimer()
props.toggleTimer()
}
return (
<div className='gameBoardDiv'>
<div id='gameboard'>
<button onClick={handleButton} className='startGameBtn btn btn-info position-absolute'>Start Game</button>
</div>
</div>
)
}