লক্ষ
এইচটিএমএল পৃষ্ঠাটি যখন রেন্ডার করা হয়, তখনই একটি স্পিনার তাত্ক্ষণিকভাবে প্রদর্শন করুন (প্রতিক্রিয়া লোড করার সময়) এবং প্রতিক্রিয়া প্রস্তুত হওয়ার পরে এটি লুকান।
স্পিনার যেহেতু খাঁটি এইচটিএমএল / সিএসএসে প্রকাশিত হয় (প্রতিক্রিয়া ডোমেনের বাইরে), প্রতিক্রিয়া দেখানো / লুকানোর প্রক্রিয়া সরাসরি নিয়ন্ত্রণ করা উচিত নয় এবং বাস্তবায়নের প্রতিক্রিয়া স্বচ্ছ হতে হবে।
সমাধান 1 - দ্য: খালি সিউডো-ক্লাস
যেহেতু আপনি কোনও ডিওএম ধারকটিতে প্রতিক্রিয়া রেন্ডার করেন - <div id="app"></div>
আপনি সেই ধারকটিতে কোনও স্পিনার যোগ করতে পারেন এবং যখন প্রতিক্রিয়া লোড হবে এবং রেন্ডার হবে তখন স্পিনার অদৃশ্য হয়ে যাবে।
প্রতিক্রিয়া মূলের অভ্যন্তরে আপনি একটি ডিওএম উপাদান (উদাহরণস্বরূপ একটি ডিভ) যুক্ত করতে পারবেন না, যেহেতু রিএ্যাকটি ReactDOM.render()
ডেকে যাওয়ার সাথে সাথে ধারকটির সামগ্রীগুলি প্রতিস্থাপন করবে । এমনকি আপনি যদি রেন্ডার করেন null
তবে সামগ্রীটি এখনও একটি মন্তব্যে প্রতিস্থাপন করা হবে - <!-- react-empty: 1 -->
। এর অর্থ হ'ল আপনি যদি প্রধান উপাদানটি মাউন্ট করার সময় লোডারটি প্রদর্শন করতে চান তবে ডেটা লোড হচ্ছে, তবে কিছুই আসলে রেন্ডার করা হয়নি, ধারকটির ভিতরে একটি লোডার মার্কআপ রাখা হয়েছে (<div id="app"><div class="loader"></div></div>
কাজ করবে না উদাহরণস্বরূপ)।
একটি কার্যপ্রণালী হ'ল প্রতিক্রিয়াশীল ধারকটিতে স্পিনার ক্লাস যুক্ত করা এবং :empty
সিউডো ক্লাস ব্যবহার করা । স্পিনারটি দৃশ্যমান হবে, যতক্ষণ না কোনও কিছুই ধারকটিতে রেন্ডার করা হয় না (মন্তব্য গণনা করা হয় না)। প্রতিক্রিয়ার সাথে সাথে মন্তব্য ব্যতীত অন্য কিছু রেন্ডার হয়ে যায়, লোডার অদৃশ্য হয়ে যাবে।
উদাহরণ 1
উদাহরণস্বরূপ আপনি এমন একটি উপাদান দেখতে পাবেন যা null
এটি প্রস্তুত না হওয়া অবধি রেন্ডার করে । ধারকটি হ'ল লোডারও - <div id="app" class="app"></div>
এবং লোডার শ্রেণিটি কেবল তখনই কাজ করবে :empty
(কোডে মন্তব্যগুলি দেখুন):
class App extends React.Component {
state = {
loading: true
};
componentDidMount() {
// this simulates an async action, after which the component will render the content
demoAsyncCall().then(() => this.setState({ loading: false }));
}
render() {
const { loading } = this.state;
if(loading) { // if your component doesn't have to wait for an async action, remove this block
return null; // render null when app is not ready
}
return (
<div>I'm the app</div>
);
}
}
function demoAsyncCall() {
return new Promise((resolve) => setTimeout(() => resolve(), 2500));
}
ReactDOM.render(
<App />,
document.getElementById('app')
);
.loader:empty {
position: absolute;
top: calc(50% - 4em);
left: calc(50% - 4em);
width: 6em;
height: 6em;
border: 1.1em solid rgba(0, 0, 0, 0.2);
border-left: 1.1em solid #000000;
border-radius: 50%;
animation: load8 1.1s infinite linear;
}
@keyframes load8 {
0% {
transform: rotate(0deg);
}
100% {
transform: rotate(360deg);
}
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.4.1/react.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.4.1/react-dom.js"></script>
<div id="app" class="loader"></div> <!-- add class loader to container -->
উদাহরণ 2
:empty
কোনও নির্বাচককে দেখানোর / আড়াল করার জন্য সিউডো ক্লাসটি ব্যবহারের ক্ষেত্রে তারতম্য , স্পিনারকে অ্যাপ কনটেয়ারে ভাইবোন উপাদান হিসাবে সেট করে এবং সংলগ্ন ভাইবাল সংযুক্তকারী ( +
) ব্যবহার করে ধারকটি খালি থাকলে যতক্ষণ না এটি প্রদর্শিত হয় :
class App extends React.Component {
state = {
loading: true
};
componentDidMount() {
// this simulates an async action, after which the component will render the content
demoAsyncCall().then(() => this.setState({ loading: false }));
}
render() {
const { loading } = this.state;
if(loading) { // if your component doesn't have to wait for async data, remove this block
return null; // render null when app is not ready
}
return (
<div>I'm the app</div>
);
}
}
function demoAsyncCall() {
return new Promise((resolve) => setTimeout(() => resolve(), 2500));
}
ReactDOM.render(
<App />,
document.getElementById('app')
);
#app:not(:empty) + .sk-cube-grid {
display: none;
}
.sk-cube-grid {
width: 40px;
height: 40px;
margin: 100px auto;
}
.sk-cube-grid .sk-cube {
width: 33%;
height: 33%;
background-color: #333;
float: left;
animation: sk-cubeGridScaleDelay 1.3s infinite ease-in-out;
}
.sk-cube-grid .sk-cube1 {
animation-delay: 0.2s;
}
.sk-cube-grid .sk-cube2 {
animation-delay: 0.3s;
}
.sk-cube-grid .sk-cube3 {
animation-delay: 0.4s;
}
.sk-cube-grid .sk-cube4 {
animation-delay: 0.1s;
}
.sk-cube-grid .sk-cube5 {
animation-delay: 0.2s;
}
.sk-cube-grid .sk-cube6 {
animation-delay: 0.3s;
}
.sk-cube-grid .sk-cube7 {
animation-delay: 0s;
}
.sk-cube-grid .sk-cube8 {
animation-delay: 0.1s;
}
.sk-cube-grid .sk-cube9 {
animation-delay: 0.2s;
}
@keyframes sk-cubeGridScaleDelay {
0%,
70%,
100% {
transform: scale3D(1, 1, 1);
}
35% {
transform: scale3D(0, 0, 1);
}
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.4.1/react.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.4.1/react-dom.js"></script>
<div id="app"></div>
<!-- add class loader to container -->
<div class="sk-cube-grid">
<div class="sk-cube sk-cube1"></div>
<div class="sk-cube sk-cube2"></div>
<div class="sk-cube sk-cube3"></div>
<div class="sk-cube sk-cube4"></div>
<div class="sk-cube sk-cube5"></div>
<div class="sk-cube sk-cube6"></div>
<div class="sk-cube sk-cube7"></div>
<div class="sk-cube sk-cube8"></div>
<div class="sk-cube sk-cube9"></div>
</div>
সমাধান 2 - প্রপস হিসাবে পাস স্পিনার "হ্যান্ডলার"
স্পিনাররা প্রদর্শন রাষ্ট্র উপর আরো একটি সূক্ষ্ম গ্রেইনড নিয়ন্ত্রণ আছে, দুই ফাংশন তৈরি showSpinner
এবং hideSpinner
, এবং সাজসরঞ্জাম মাধ্যমে রুট ধারক তাদের পাস। ফাংশনগুলি ডিওএমকে পরিচালনা করতে পারে, বা স্পিনারকে নিয়ন্ত্রণ করার জন্য যা প্রয়োজন তা করতে পারে। এইভাবে, প্রতিক্রিয়াটি "বাইরের বিশ্বের" সম্পর্কে সচেতন নয় বা ডমকে সরাসরি নিয়ন্ত্রণ করার প্রয়োজন নেই। আপনি পরীক্ষার জন্য ফাংশনগুলি সহজেই প্রতিস্থাপন করতে পারেন, বা আপনার যদি যুক্তিটি পরিবর্তন করতে হয় এবং আপনি এগুলি প্রতিক্রিয়া গাছের অন্যান্য উপাদানগুলিতে দিতে পারেন।
উদাহরণ 1
const loader = document.querySelector('.loader');
// if you want to show the loader when React loads data again
const showLoader = () => loader.classList.remove('loader--hide');
const hideLoader = () => loader.classList.add('loader--hide');
class App extends React.Component {
componentDidMount() {
this.props.hideLoader();
}
render() {
return (
<div>I'm the app</div>
);
}
}
// the setTimeout simulates the time it takes react to load, and is not part of the solution
setTimeout(() =>
// the show/hide functions are passed as props
ReactDOM.render(
<App
hideLoader={hideLoader}
showLoader={showLoader}
/>,
document.getElementById('app')
)
, 1000);
.loader {
position: absolute;
top: calc(50% - 4em);
left: calc(50% - 4em);
width: 6em;
height: 6em;
border: 1.1em solid rgba(0, 0, 0, 0.2);
border-left: 1.1em solid #000000;
border-radius: 50%;
animation: load8 1.1s infinite linear;
transition: opacity 0.3s;
}
.loader--hide {
opacity: 0;
}
@keyframes load8 {
0% {
transform: rotate(0deg);
}
100% {
transform: rotate(360deg);
}
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.4.1/react.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.4.1/react-dom.js"></script>
<div id="app"></div>
<div class="loader"></div>
উদাহরণ 2 - হুকস
এই উদাহরণটি useEffect
উপাদানটি মাউন্ট করার পরে স্পিনারকে আড়াল করতে হুক ব্যবহার করে ।
const { useEffect } = React;
const loader = document.querySelector('.loader');
// if you want to show the loader when React loads data again
const showLoader = () => loader.classList.remove('loader--hide');
const hideLoader = () => loader.classList.add('loader--hide');
const App = ({ hideLoader }) => {
useEffect(hideLoader, []);
return (
<div>I'm the app</div>
);
}
// the setTimeout simulates the time it takes react to load, and is not part of the solution
setTimeout(() =>
// the show/hide functions are passed as props
ReactDOM.render(
<App
hideLoader={hideLoader}
showLoader={showLoader}
/>,
document.getElementById('app')
)
, 1000);
.loader {
position: absolute;
top: calc(50% - 4em);
left: calc(50% - 4em);
width: 6em;
height: 6em;
border: 1.1em solid rgba(0, 0, 0, 0.2);
border-left: 1.1em solid #000000;
border-radius: 50%;
animation: load8 1.1s infinite linear;
transition: opacity 0.3s;
}
.loader--hide {
opacity: 0;
}
@keyframes load8 {
0% {
transform: rotate(0deg);
}
100% {
transform: rotate(360deg);
}
}
<script crossorigin src="https://unpkg.com/react@16/umd/react.development.js"></script>
<script crossorigin src="https://unpkg.com/react-dom@16/umd/react-dom.development.js"></script>
<div id="app"></div>
<div class="loader"></div>