Javascript React—从父/同级组件触发子方法的最佳方式
我对React还不熟悉,也许我的逻辑有点混乱: 我有游戏组件,它有两个孩子:棋盘和计时器 棋盘上有一个开始游戏的按钮。当我开始游戏时,我想启动计时器。有没有一种方法可以直接调用函数来启动计时器,从Board? 我试图从游戏中发送一个函数到棋盘,该函数会改变游戏中的一些状态,但我不知道如何触发计时器的开始停止时间我的想法是使用效果,但我不知道是否有更简单的方法 谢谢你的帮助 Game.jsxJavascript React—从父/同级组件触发子方法的最佳方式,javascript,reactjs,Javascript,Reactjs,我对React还不熟悉,也许我的逻辑有点混乱: 我有游戏组件,它有两个孩子:棋盘和计时器 棋盘上有一个开始游戏的按钮。当我开始游戏时,我想启动计时器。有没有一种方法可以直接调用函数来启动计时器,从Board? 我试图从游戏中发送一个函数到棋盘,该函数会改变游戏中的一些状态,但我不知道如何触发计时器的开始停止时间我的想法是使用效果,但我不知道是否有更简单的方法 谢谢你的帮助 Game.jsx function Game(){ return( <div> <B
function Game(){
return(
<div>
<Board>
<Timer>
</div>
)
}
Board.jsx
function Board(){
/* logic game*/
return (
<Button>Start game</button>
)
}
timer.jsx
function Timer(){
/* methods timer*/
function startStopTime{ /* code*/}
function resetTimer{ /* code*/}
return (
<div>{timeRunningGame}</div>
)
}
我认为你在计时器中使用效果的想法是正确的 这是一个实现,其他的存在 Timer.jsx
const Timer = ({ isRunning, onReset }) => {
const [time, setTime] = useState(0);
useEffect(() => {
const timer = isRunning
// if true, start timer
? setInterval(() => setTime(t => t + 0.1), 100)
// else reset time back to 0
: setTime(0);
// provide cleanup function
return () => clearInterval(timer);
}, [isRunning]);
return (
<>
<div>{Number(time).toFixed(1)}</div>
{isRunning && (
<button type="button" onClick={onReset}>
Reset
</button>
)}
</>
);
};
Game.jsx管理正在启动和传递的计时器的状态
const Game = () => {
const [isRunning, setIsRunning] = useState(false);
const runTimer = run => () => setIsRunning(run);
return (
<>
<Board onStartGame={runTimer(true)} />
<Timer isRunning={isRunning} onReset={runTimer(false)} />
</>
);
};
你对此做了哪些研究?这是一个非常常见的问题,您只需从父组件传递一个道具,管理父组件上的状态,然后将更新的值传递给其他组件。您可以使用useState在父组件中设置状态,然后将状态作为道具传递给子组件。或者使用诸如Redux之类的状态管理库进行单向数据流。我知道如何传递状态,但如何触发函数?我是否需要重新编码该函数以使其不是函数?你不能,但你可以通过回调更新某个状态来启动计时器,并将该按钮放置在棋盘上,并将道具传递给计时器以从“共同祖先”游戏开始/停止。有人可以发布一个示例吗,因为我不知道状态如何触发启动。非常感谢!!:
const Game = () => {
const [isRunning, setIsRunning] = useState(false);
const runTimer = run => () => setIsRunning(run);
return (
<>
<Board onStartGame={runTimer(true)} />
<Timer isRunning={isRunning} onReset={runTimer(false)} />
</>
);
};