[reactjs] 반응-DOM이 렌더링되는 동안 로딩 화면이 표시됩니까?
Google Adsense 애플리케이션 페이지의 예입니다. 메인 페이지 이전에 표시된 로딩 화면이 나타납니다.
React와 동일한 작업을 수행하는 방법을 모르겠습니다 .React 구성 요소로 렌더링 된 로딩 화면을 만들면 DOM이 렌더링 될 때까지 기다려야하기 때문에 페이지가로드되는 동안 표시되지 않기 때문입니다.
업데이트 :
스크린 로더를 넣고 index.html
React componentDidMount()
수명주기 방법으로 제거하여 접근 방식의 예를 만들었습니다 .
답변
로드 아이콘을 html 파일 (예 : index.html)에 배치하면 html 파일이로드 된 후 바로 아이콘을 볼 수 있습니다.
앱이 로딩을 마치면 라이프 사이클 후크에서 로딩 아이콘을 제거 할 수 componentDidMount
있습니다.
답변
목표
html 페이지가 렌더링되면 스피너를 즉시 표시하고 (React가로드되는 동안) React가 준비되면 숨 깁니다.
스피너는 순수한 HTML / CSS (React 도메인 외부)로 렌더링되므로 React는 표시 / 숨김 프로세스를 직접 제어하지 않아야하며 구현은 React에 투명해야합니다.
해결 방법 1-: 비상 의사 클래스
반응을 DOM 컨테이너에 렌더링하기 때문에 <div id="app"></div>
해당 컨테이너에 스피너를 추가 할 수 있으며 반응이로드되어 렌더링되면 스피너가 사라집니다.
React ReactDOM.render()
가 호출 되는 즉시 컨테이너의 내용을 대체하므로 반응 루트 내에 DOM 요소 (예 : div)를 추가 할 수 없습니다 . 렌더링하더라도 null
내용은 여전히 주석으로 대체됩니다 <!-- react-empty: 1 -->
. 즉, 주요 구성 요소가 마운트되는 동안 로더를 표시하려는 경우 데이터가로드되지만 실제로 아무것도 렌더링 <div id="app"><div class="loader"></div></div>
되지 않으면 컨테이너 ( 예 🙂 내부에 배치 된 로더 마크 업 이 작동하지 않습니다.
해결 방법은 스피너 클래스를 반응 컨테이너에 추가하고 :empty
의사 클래스를 사용하는 것 입니다. 컨테이너에 아무것도 렌더링되지 않는 한 스피너가 표시됩니다 (코멘트는 포함되지 않음). 반응이 주석 이외의 것을 렌더링하자마자 로더가 사라집니다.
실시 예 1
이 예에서는 null
준비 될 때까지 렌더링되는 구성 요소를 볼 수 있습니다 . 컨테이너도 로더입니다- <div id="app" class="app"></div>
그리고 로더의 클래스는 그것이 작동하는 경우에만 작동합니다 :empty
(코드 주석 참조).
실시 예 2
:empty
의사 클래스를 사용하여 선택기를 표시하거나 숨기는 변형 은 스피너를 앱 컨테이너의 형제 요소로 설정하고 인접한 형제 조합기 ( +
)를 사용하여 컨테이너가 비어있는 동안 표시하는 것입니다 .
해결 방법 2- 스피너 “핸들러”를 소품으로 전달
, 스피 표시 상태를 통해보다 세밀하게 제어 할 수 있습니다 두 가지 기능을 만들려면 showSpinner
하고 hideSpinner
, 소품을 통해 루트 컨테이너로 전달합니다. 함수는 DOM을 조작하거나 스피너를 제어하는 데 필요한 모든 작업을 수행 할 수 있습니다. 이런 식으로 React는 “외부 세계”를 인식하지 못하고 DOM을 직접 제어 할 필요가 없습니다. 테스트 할 기능을 쉽게 교체하거나 로직을 변경해야하는 경우 React 트리의 다른 구성 요소로 전달할 수 있습니다.
실시 예 1
예 2-후크
이 예에서는 useEffect
구성 요소가 마운트 된 후 후크를 사용하여 스피너를 숨 깁니다.
답변
이에 대한 해결 방법은 다음과 같습니다.
렌더링 함수에서 다음과 같이하십시오.
constructor() {
this.state = { isLoading: true }
}
componentDidMount() {
this.setState({isLoading: false})
}
render() {
return(
this.state.isLoading ? *showLoadingScreen* : *yourPage()*
)
}
생성자에서 isLoading을 true로, componentDidMount에서 false를 초기화합니다.
답변
위의 유스 케이스에 대해 드롭 인, 제로 구성 및 제로 종속성 라이브러리를 찾는 사람이 있다면 pace.js ( http://github.hubspot.com/pace/docs/welcome/ )를 사용해보십시오 .
이벤트 (ajax, readyState, history pushstate, js event loop 등)에 자동으로 연결되어 사용자 정의 가능한 로더를 보여줍니다.
리 액트 / 릴레이 프로젝트 (리 액트 라우터, 릴레이 요청을 사용하여 탐색 변경 처리)
와 잘 작동했습니다.
답변
React 앱이 방대한 경우 페이지가로드 된 후 앱이 시작되고 실행되는 데 실제로 시간이 걸립니다. 앱의 React 부분을에 마운트한다고 가정 해보십시오 #app
. 일반적으로 index.html의이 요소는 단순히 빈 div입니다.
<div id="app"></div>
대신 페이지로드와 DOM에 대한 초기 React 앱 렌더링 사이에서 더 잘 보이도록 몇 가지 스타일과 이미지를 배치하십시오.
<div id="app">
<div class="logo">
<img src="/my/cool/examplelogo.svg" />
</div>
<div class="preload-title">
Hold on, it's loading!
</div>
</div>
페이지가로드되면 index.html의 원래 내용을 즉시 볼 수 있습니다. 곧 React가 렌더링 된 컴포넌트의 전체 계층을이 DOM 노드에 마운트 할 준비가되면 실제 앱이 표시됩니다.
참고 class
하지 className
. 이것을 html 파일에 넣어야하기 때문입니다.
SSR을 사용하면 페이지가로드 된 후 사용자가 실제 앱을 실제로 볼 수 있기 때문에 작업이 덜 복잡해집니다.
답변
이것은 루트를ReactDOM.render()
제어 하기 전에 발생 합니다 <div>
. 즉, 앱이 해당 시점까지 마운트되지 않았습니다.
따라서 index.html
루트 안의 파일에 로더를 추가 할 수 있습니다 <div>
. 그리고 React가 인수 할 때까지 화면에 표시됩니다.
가장 적합한 로더 요소 svg
를 애니메이션으로 사용할 수 있습니다 .
수명주기 방법에서 제거 할 필요는 없습니다. 아래 GIF에서 볼 수 있듯이 React는 루트 의 모든 하위 요소를 <div>
렌더링 된로 대체합니다 <App/>
.
index.html
<head>
<style>
.svgLoader {
animation: spin 0.5s linear infinite;
margin: auto;
}
.divLoader {
width: 100vw;
height: 100vh;
display: flex;
align-items: center;
justify-content: center;
}
@keyframes spin {
0% { transform: rotate(0deg); }
100% { transform: rotate(360deg); }
}
</style>
</head>
<body>
<div id="root">
<div class="divLoader">
<svg class="svgLoader" viewBox="0 0 1024 1024" width="10em" height="10em">
<path fill="lightblue"
d="PATH FOR THE LOADER ICON"
/>
</svg>
</div>
</div>
</body>
index.js
실행 debugger
하기 전에 페이지를 검사하는 데 사용 ReactDOM.render()
합니다.
import React from "react";
import ReactDOM from "react-dom";
import "./styles.css";
function App() {
return (
<div className="App">
<h1>Hello CodeSandbox</h1>
<h2>Start editing to see some magic happen!</h2>
</div>
);
}
debugger; // TO INSPECT THE PAGE BEFORE 1ST RENDER
const rootElement = document.getElementById("root");
ReactDOM.render(<App />, rootElement);
답변
요즘에는 React 16.8에서도 후크를 사용할 수 있습니다.
import React, { useState, useEffect } from 'react';
const App = () => {
const [ spinner, setSpinner ] = useState(true);
// It will be executed before rendering
useEffect(() => {
setTimeout(() => setSpinner(false), 1000)
}, []);
// [] means like componentDidMount
return !spinner && <div>Your content</div>;
};
export default App;