这是我在这里的第一个帖子!
我正在React中创建一个 Pomodoro 。我的目标很简单。我正在创建一个Pomodoro时钟,能够在JavaScript中成功完成此操作,但是具有React组件体系结构。但是我遇到了一些问题。
所以我的App组件有3个子级:Session
,Timer
和Break
应用组件
let [fromSession, setFromSession] = useState();
let [isSession, setIsSession] = useState();
let [fromBreak, setFromBreak] = useState();
let [isBreak, setIsBreak] = useState();
const fromSessionFunction = w => {
setFromSession(w);
}
const sessionTrueOrNot = x => {
setIsSession(x);
}
const fromBreakFunction = y => {
setFromBreak(y);
}
const breakTrueOrNot = z => {
setIsBreak(z);
}
if(isBreak === true) {
isSession = false;
}
if (isSession === true) {
isBreak = false;
}
console.log('from App', isSession, isBreak)
return (
<div className='app-background center'>
<h1>Pomodoro Timer</h1>
<div className='flex'>
<Session sessionFunctionFromApp={fromSessionFunction} sessionTrueOrNot={sessionTrueOrNot}/>
<Timer sessionFromApp={fromSession} isSessionFromApp={isSession} breakFromApp={fromBreak} isBreakFromApp={isBreak}/>
<Break breakFunctionFromApp={fromBreakFunction} breakTrueOrNot={breakTrueOrNot}/>
</div>
</div>
)
}
export default App;
会话组件
let [sessionTime, setSessionTime] = useState(25);
let [sessionTrue, setSessionTrue] = useState();
const decreaseSessionFunction = () => {
setSessionTime(sessionTime -= 1);
setSessionTrue(true);
}
const increaseSessionFunction = () => {
setSessionTime(sessionTime += 1);
setSessionTrue(true);
console.log(sessionTrue);
}
useEffect(() => {
setSessionTrue(true);
}, []);
sessionFunctionFromApp(sessionTime);
sessionTrueOrNot(sessionTrue);
return (
<div>
<h3>Session</h3>
<p>{sessionTime}:00</p>
<button className='ui purple basic button' onClick={() => decreaseSessionFunction()}>-</button>
<button className='ui purple basic button' onClick={() => increaseSessionFunction()}>+</button>
</div>
)
}
export default Session;
计时器组件
let name, display;
if(isSessionFromApp) {
name = 'Timer for Session';
display = sessionFromApp;
}
if(isBreakFromApp) {
name = 'Timer for Break';
display = breakFromApp;
}
return (
<div>
<h2>{name}</h2>
<p id='big-font'>{display}:00</p>
<button className='ui blue basic button'>Start</button>
<button className='ui blue basic button'>Stop</button>
<button className='ui blue basic button'>Restart</button>
</div>
)
}
export default Timer;
中断组件
let [breakTime, setBreakTime] = useState(10);
let [breakTrue, setBreakTrue] = useState();
const decreaseBreakFunction = () => {
setBreakTime(breakTime -= 1);
setBreakTrue(true);
}
const increaseBreakFunction = () => {
setBreakTime(breakTime += 1);
setBreakTrue(true);
console.log(breakTrue);
}
useEffect(() => {
setBreakTrue(false)
}, []);
breakFunctionFromApp(breakTime);
breakTrueOrNot(breakTrue);
return (
<div>
<h3>Break</h3>
<p>{breakTime}:00</p>
<button className='ui violet basic button' onClick={() => decreaseBreakFunction()}>-</button>
<button className='ui violet basic button' onClick={() => increaseBreakFunction()}>+</button>
</div>
)
}
export default Break;
好吧,实际上,我唯一想做的就是从App像现在这样console.log
时,它会打印出true
或false
这很好。
我希望Session
在默认情况下为true,而Break
为false。所以,我想要的是单击Break的+
时,尽管App中的console.log
更改为false true。从Break组件的第15行说是false。
为什么会这样?
如果这是假的,那么应用程序怎么会说假的真的?
最后,当我单击Session的+
时,Session组件的第15行再次显示为true,而App打印的结果为false。
感谢您的阅读,非常感谢您的帮助,我了解我的代码反映出我是一个初学者。
答案 0 :(得分:1)
您看到Break
和App
说出关于看似相同值breakTrue
的冲突。但实际上它们是两个价值。这是因为setState()
是一个异步函数。您不能期望它会立即更改其状态。
En bref,您的代码执行顺序如下:
[PSEUDO CODE]
1. Break: setBreakTrue(true)
// issue an async update command, doesn't take effect yet.
2. Break: console.log(breakTrue)
// sync func, instant effect, so you see the old value `false` before previous command
3. App: console.log('from App', isBreak)
// exec in the re-render cycle triggered by 1st command, thus reflects the new value `true`.
在此附上demoboard。检查Break
文件ln:22,我添加了:
useEffect(() => console.log('breakTrue (async):', breakTrue))
此console.log
包装在useEffect
内,因此它在执行 setState
命令后执行,因此您将看到{{ 1}}成为breakTrue
。
附带的是对该应用程序的重写:
https://frontarm.com/demoboard/?id=aa46b63b-a020-4041-b8a8-14c2174c647e