【问题标题】:How to display and animate React Component depending to result of condition with React Spring?如何根据 React Spring 的条件结果显示和动画 React 组件?
【发布时间】:2020-08-07 07:37:58
【问题描述】:

我正在努力根据条件结果渲染 React 组件。为了更准确,我正在开发闹钟应用程序,您可以在其中设置闹钟应该“响”的时间。

有 3 个函数通过 useEffect() 每秒更新一次。

  1. currentTime() - 获取当前时间并插入状态

    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() - 获取当前日期并插入状态

    function currentDate(){
     let date = new Date();
     let day = days[date.getDay()];
    
     setTime(prevState => ({
     ...prevState,
     currentDay:day
     }))
    }
    
  3. checkTime() - 检查alarmHours 状态是否为空。仅当设置了警报时,此状态才有价值。

    function checkTime(){
     if(time.alarmHours && time.alarmMinutes){
      if(time.currentHour === time.alarmHours && time.currentMinute === time.alarmMinutes && 
      time.currentSecond === '00'){
        setShowRing(true);
       }
      }
     }
    

要设置闹钟,您必须点击 SET ALARM 按钮,该按钮目前位于右上角。 点击后出现Alarm.js组件,淡入淡出。这些转换是使用 React Spring Transitions 完成的。

Alarm.js 组件作为 App.js 的 prop 传递函数。该函数应该从 Alarm.js 中获取所有填充的信息(警报消息和警报响起的时间)并将它们存储在状态中。

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 here.

【问题讨论】:

    标签: javascript reactjs react-spring


    【解决方案1】:

    您在这里有点纠结,因为如果您在App 中有条件地渲染组件,则在卸载组件时Ring 中的过渡离开将没有足够的时间来完成。转换逻辑必须存在于App 中,或者您必须像使用Alarm 一样持续渲染Ring。它还需要通过 props 绑定到showRing 状态——它无法控制自己的状态,因为它依赖于父级。

    我建议像这样持续渲染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>
      );
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-10-07
      • 2020-09-28
      • 2021-01-10
      • 2020-08-28
      • 2020-04-11
      • 1970-01-01
      相关资源
      最近更新 更多