在React中,组件的重新呈现通常是由状态(state)或属性(props)的变化触发的。当输入更改时,如果组件的状态或属性依赖于这些输入,组件会重新渲染。
问题:输入更改时,倒计时组件意外重新呈现。
原因:
React.memo
:对倒计时组件进行记忆化处理,避免不必要的重新渲染。import React, { useState, useEffect, memo } from 'react';
const Countdown = memo(({ endTime }) => {
const [timeLeft, setTimeLeft] = useState(calculateTimeLeft(endTime));
useEffect(() => {
const timer = setTimeout(() => {
setTimeLeft(calculateTimeLeft(endTime));
}, 1000);
return () => clearTimeout(timer);
}, [endTime]);
return <div>{timeLeft}</div>;
});
function calculateTimeLeft(endTime) {
const difference = +new Date(endTime) - +new Date();
let timeLeft = {};
if (difference > 0) {
timeLeft = {
days: Math.floor(difference / (1000 * 60 * 60 * 24)),
hours: Math.floor((difference / (1000 * 60 * 60)) % 24),
minutes: Math.floor((difference / 1000 / 60) % 60),
seconds: Math.floor((difference / 1000) % 60),
};
}
return timeLeft;
}
const App = () => {
const [input, setInput] = useState('');
const [endTime, setEndTime] = useState('');
useEffect(() => {
setEndTime(input);
}, [input]);
return (
<div>
<input value={input} onChange={(e) => setInput(e.target.value)} />
<Countdown endTime={endTime} />
</div>
);
};
export default App;
useCallback
或useMemo
:在父组件中使用这些钩子函数来记忆化传递给倒计时组件的函数或值,避免不必要的重新渲染。import React, { useState, useEffect, useCallback } from 'react';
const Countdown = ({ endTime, onTimeUpdate }) => {
const [timeLeft, setTimeLeft] = useState(calculateTimeLeft(endTime));
useEffect(() => {
const timer = setTimeout(() => {
setTimeLeft(calculateTimeLeft(endTime));
onTimeUpdate(timeLeft);
}, 1000);
return () => clearTimeout(timer);
}, [endTime, onTimeUpdate]);
return <div>{timeLeft}</div>;
};
function calculateTimeLeft(endTime) {
const difference = +new Date(endTime) - +new Date();
let timeLeft = {};
if (difference > 0) {
timeLeft = {
days: Math.floor(difference / (1000 * 60 * 60 * 24)),
hours: Math.floor((difference / (1000 * 60 * 60)) % 24),
minutes: Math.floor((difference / 1000 / 60) % 60),
seconds: Math.floor((difference / 1000) % 60),
};
}
return timeLeft;
}
const App = () => {
const [input, setInput] = useState('');
const [endTime, setEndTime] = useState('');
const handleTimeUpdate = useCallback((timeLeft) => {
console.log(timeLeft);
}, []);
useEffect(() => {
setEndTime(input);
}, [input]);
return (
<div>
<input value={input} onChange={(e) => setInput(e.target.value)} />
<Countdown endTime={endTime} onTimeUpdate={handleTimeUpdate} />
</div>
);
};
export default App;
通过这些方法,可以有效避免倒计时组件在输入更改时意外重新呈现的问题。
领取专属 10元无门槛券
手把手带您无忧上云