【发布时间】:2019-08-19 22:40:54
【问题描述】:
我的目标是能够有一个儿童可以访问的计时器。问题是只有少数组件需要秒值,但许多组件需要能够操作计时器(暂停、更改值、重置等)。我的解决方案是将所有子项都包含在其中,但访问它的子项仍会在每次第二次更新时呈现 - 即使我没有在上下文中解压缩秒数。
这是包装器:
import * as React from 'react';
import Timer, {ITimerSettings} from '../../utilities/Timer';
export const TimerContext = React.createContext({
seconds: null,
setTimer: null,
timer: null
});
export const TimerProvider = TimerContext.Provider;
export const TimerConsumer = TimerContext.Consumer;
interface ITimerWrapperProps {
isPaused: boolean;
isReady: boolean;
children: any;
}
const TimerWrapper: React.FC<ITimerWrapperProps> = ({isReady, isPaused, children}) => {
const timer = React.useRef<Timer>(new Timer());
const [seconds, setSeconds] = React.useState<number>(null);
React.useEffect(() => {
if (isReady && timer.current && timer.current.duration) {
isPaused ? timer.current.stop() : timer.current.start();
}
}, [isReady, isPaused]);
const setTimer = React.useCallback((settings: Partial<ITimerSettings>): void => {
if (timer.current) {
timer.current.reset({
callback: i => setSeconds(i),
...settings
});
}
}, []);
return (
<TimerProvider value={{seconds, timer, setTimer}}>
{children}
</TimerProvider>
);
};
export default React.memo(TimerWrapper);
这是孩子访问它的方式:
const {timer, setTimer} = React.useContext(TimerContext);
我的问题是,为什么每次更新秒数时孩子都会重新渲染,我该如何防止它?我是否需要拆分上下文,以便有一个用于秒数和一个用于计时器?
【问题讨论】:
-
尝试直接传递计时器引用,而不是
timer.current,因为timer.current每次更新计时器都有一个新值(如果我理解正确的话)并尝试在引用中存储秒数。您可能不想在每个计时器滴答声中更新任何道具 -
好主意 - 我尝试只传递 ref 并使用 timer.current 访问它,但这似乎不起作用。
标签: reactjs react-hooks