これは、ローディングスピナーを作成しながら、2019年にこれを解決した方法です。React機能コンポーネントを使用しています。
子のSpinnerコンポーネントを持つ親のAppコンポーネントがあります。
アプリには、アプリが読み込まれているかどうかの状態があります。アプリの読み込み中、Spinnerは通常どおりレンダリングされます。アプリが読み込まれていない(isLoading
false)場合、SpinnerはプロップでレンダリングされますshouldUnmount
。
App.js:
import React, {useState} from 'react';
import Spinner from './Spinner';
const App = function() {
const [isLoading, setIsLoading] = useState(false);
return (
<div className='App'>
{isLoading ? <Spinner /> : <Spinner shouldUnmount />}
</div>
);
};
export default App;
スピナーには、それが非表示かどうかの状態があります。最初は、デフォルトの小道具と状態で、Spinnerは通常どおりレンダリングされます。Spinner-fadeIn
このクラスは、それがフェードインアニメーション化します。場合はスピナーは小道具受け取るshouldUnmount
ことがでレンダリングをSpinner-fadeOut
、それがフェードアウトアニメーション、代わりにクラス。
ただし、フェードアウト後にコンポーネントをアンマウントすることも必要でした。
この時点でonAnimationEnd
、上の@ pranesh-raviのソリューションと同様に、React合成イベントを使用しようとしましたが、機能しませんでした。代わりにsetTimeout
、アニメーションと同じ長さの遅延で状態を非表示に設定するために使用しました。スピナーはの遅延後に更新され、isHidden === true
何もレンダリングされません。
ここで重要なのは、親が子をマウント解除せず、マウントを解除するタイミングを子に通知し、マウント解除ビジネスの世話をした後、子供がマウント解除することです。
Spinner.js:
import React, {useState} from 'react';
import './Spinner.css';
const Spinner = function(props) {
const [isHidden, setIsHidden] = useState(false);
if(isHidden) {
return null
} else if(props.shouldUnmount) {
setTimeout(setIsHidden, 500, true);
return (
<div className='Spinner Spinner-fadeOut' />
);
} else {
return (
<div className='Spinner Spinner-fadeIn' />
);
}
};
export default Spinner;
Spinner.css:
.Spinner {
position: fixed;
display: block;
z-index: 999;
top: 50%;
left: 50%;
margin: -40px 0 0 -20px;
height: 40px;
width: 40px;
border: 5px solid #00000080;
border-left-color: #bbbbbbbb;
border-radius: 40px;
}
.Spinner-fadeIn {
animation:
rotate 1s linear infinite,
fadeIn .5s linear forwards;
}
.Spinner-fadeOut {
animation:
rotate 1s linear infinite,
fadeOut .5s linear forwards;
}
@keyframes fadeIn {
0% {
opacity: 0;
}
100% {
opacity: 1;
}
}
@keyframes fadeOut {
0% {
opacity: 1;
}
100% {
opacity: 0;
}
}
@keyframes rotate {
100% {
transform: rotate(360deg);
}
}