react-intersection-observer
関数コンポーネントでなんとか使用できます。ただし、クラスコンポーネントで使用するとうまくいきませんでした。ドキュメントに従おうとしましたが、次のエラーが表示されます。
Invariant failed: react-intersection-observer: No DOM node found. Make sure you forward "ref" to the root DOM element you want to observe.
私は何を間違っていますか?前もって感謝します。
擬似コード
- 要素がビューポートに表示されたときにアニメーションをトリガーします。
import React, { Component } from "react";
import { Container, Row, Col } from "react-grid-system";
import { motion } from "framer-motion";
import { InView } from "react-intersection-observer";
let years, days, hours, mins, secs;
function upTime(countTo) {
var now = new Date();
countTo = new Date(countTo);
var difference = now - countTo;
years = Math.floor(difference / (60 * 60 * 1000 * 24) / 365);
days = Math.floor(difference / (60 * 60 * 1000 * 24));
hours = Math.floor((difference / (60 * 60 * 1000 * 24)) * 24);
mins = Math.floor((difference / (60 * 60 * 1000 * 24)) * 24 * 60);
secs = mins * 60;
clearTimeout(upTime.to);
upTime.to = setTimeout(function() {
upTime(countTo);
}, 1000);
}
export default class Timer extends Component {
state = {
y: 0,
d: 0,
h: 0,
m: 0,
s: 0,
toggle: true
};
componentDidMount() {
// Set inital seconds
upTime("may,05,2006,00:00:00");
let currentSec = secs;
this.myInterval = setInterval(() => {
upTime("may,05,2006,00:00:00");
currentSec += 1;
this.setState({
y: years,
d: days,
h: hours,
m: mins,
s: currentSec
});
}, 1000);
}
componentWillUnmount() {
clearInterval(this.myInterval);
}
render() {
const { y, h, m, s } = this.state;
const style = {
listStyle: "none",
fontFamily: "Soleil",
fontSize: "200px",
lineHeight: "220px",
color: "black",
textAlign: "left"
};
// Animation list
const list = {
visible: {
opacity: 1,
transition: { staggerChildren: 0.06 }
},
hidden: {
opacity: 0,
transition: {}
}
};
// Animation list
const item = {
visible: {
opacity: 1,
y: 0,
transition: { ease: "backInOut", duration: 0.8 }
},
hidden: { opacity: 0, y: 100 }
};
// Conditional render
if (y !== 0) {
return (
<Container fluid>
<Row>
<Col offset={{ xl: 1 }}>
<InView>
{({ inView, ref, entry }) => (
<motion.ul
ref={ref}
style={style}
initial="hidden"
animate={inView ? "visible" : "hidden"}
variants={list}
>
<motion.li variants={item}>{y}Y</motion.li>
<motion.li variants={item}>{h}H</motion.li>
<motion.li variants={item}>{m}M</motion.li>
<motion.li variants={item}>{s}</motion.li>
</motion.ul>
)}
</InView>
</Col>
</Row>
</Container>
);
} else {
return <div>"Loading..."</div>;
}
}
}