[英]How to display and animate React Component depending to result of condition with React Spring?
我正在努力根據條件結果渲染 React 組件。 更准確地說,我正在開發鬧鍾應用程序,您可以在其中設置鬧鍾應該“響起”的時間。
有 3 個函數通過useEffect() 每秒更新一次。
currentTime() - 獲取當前時間並插入 state
function currentTime(){ let time = new Date().toLocaleTimeString('it-IT'); let hours = time.substr(0,2); let minutes = time.substr(3,2); let seconds = time.substring(time.length-2) setTime(prevState => ({...prevState, currentHour:hours, currentMinute:minutes, currentSecond:seconds })) }
currentDate() - 獲取當前日期並插入 state
function currentDate(){ let date = new Date(); let day = days[date.getDay()]; setTime(prevState => ({...prevState, currentDay:day })) }
checkTime() - 檢查 alarmHours state 是否為空。 此 state 只有在設置了警報時才有價值。
function checkTime(){ if(time.alarmHours && time.alarmMinutes){ if(time.currentHour === time.alarmHours && time.currentMinute === time.alarmMinutes && time.currentSecond === '00'){ setShowRing(true); } } }
要設置警報,您必須單擊設置警報按鈕,該按鈕目前位於右上角。 點擊后出現Alarm.js組件,淡入淡出。 這些轉換是使用React Spring 轉換完成的。
將 function 作為App.js的道具傳遞給此Alarm.js組件。 這個 function 應該從Alarm.js中獲取所有填充的信息(警報消息和警報響起的時間)並將它們存儲在 state 中。
function getAlarm(){
let description = document.getElementById('text').value;
let hours = document.getElementById('hours').value;
let minutes = document.getElementById('minutes').value;
setTime(prevState => ({
...prevState,
message:description,
alarmHours:hours,
alarmMinutes:minutes,
}));
}
在我之前的問題中,我問的是如何在滿足條件且當前時間等於設置的時間時調用此 Ring 組件。 有人告訴我這樣做:
const [showRing,setShowRing] = useState(false);
然后當滿足 checkTime 條件時
setShowRing(true);
在 App.js 渲染中:
{showRing && <Ring message={time.message} turnOff={()=>setShowRing(false)} />}
有用。 但是沒有過渡,如果它像 Alarm.js 一樣完全分離在自己的文件中會更快樂。 我試圖向它添加過渡,但它甚至沒有顯示。 最好的選擇是在條件下像 Alarm.js 一樣調用它,所有這些轉換都在它自己的文件中進行。 我是說
function checkTime(){
if(time.alarmHours && time.alarmMinutes){
if(time.currentHour === time.alarmHours && time.currentMinute === time.alarmMinutes &&
time.currentSecond === '00'){
return <Ring />
}
}
}
但它不起作用。 即使我嘗試在 Ring.js 中添加這些轉換。 請問有沒有人可以幫我解決這個問題? 我真的很感激。
CODESANDBOX 在這里。
你在這里有點束縛,因為如果你在App
中有條件地渲染組件,當組件被卸載時, Ring
中的過渡離開將沒有足夠的時間來完成。 要么轉換邏輯必須存在於App
中,要么你必須像使用Alarm
一樣持續渲染Ring
。 它還需要通過道具綁定到showRing
state - 它無法控制自己的state,因為它取決於父級。
我建議像這樣持續渲染Ring
組件:
<Ring message={time.message} showRing={showRing} turnOff={() => setShowRing(false)} />
在里面:
function Ring(props) {
const { message, turnOff, showRing } = props;
const ringTransitions = useTransition(showRing, null, {
from: { position: "absolute", opacity: 0 },
enter: { opacity: 1 },
leave: { opacity: 0 }
});
return (
<div>
{ringTransitions.map(
({ item, key, props }) =>
item && (
<animated.div key={key} style={props} className="overlay">
<div className="inputBox">
<h3>{message}</h3>
<a onClick={turnOff}>TURN OFF</a>
</div>
</animated.div>
)
)}
</div>
);
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.