簡體   English   中英

如何根據 React Spring 的條件結果顯示和動畫 React 組件?

[英]How to display and animate React Component depending to result of condition with React Spring?

我正在努力根據條件結果渲染 React 組件。 更准確地說,我正在開發鬧鍾應用程序,您可以在其中設置鬧鍾應該“響起”的時間。

有 3 個函數通過useEffect() 每秒更新一次。

  1. 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 })) }
  2. currentDate() - 獲取當前日期並插入 state

     function currentDate(){ let date = new Date(); let day = days[date.getDay()]; setTime(prevState => ({...prevState, currentDay:day })) }
  3. 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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM