Reputation: 2167
I'm using react and I'm trying to display loader when dom is rendering. But I'm really not sure why this ternary operation isn't working. What am I doing wrong here?
import React, { Component } from 'react';
import logo from './logo.svg';
class App extends React.Component
{
constructor()
{
super();
this.state = {isLoading: true}
console.log(this.state.isLoading);
}
componentDidMount()
{
this.setState ({isLoading: false})
console.log("componentDidMount");
}
render()
{
return(
this.state.isLoading ?
<div><img src={logo} className="App-logo" alt="logo" /></div>
:
<div> yourPage </div>
)
}
}
export default App;
It shows yourPage every time does not show logo image (loader image)
Upvotes: 0
Views: 2534
Reputation: 141
Here it is...
constructor(props) {
this.state = {
x: ...
y: ...
isLoading: true
}
}
ComponentDidMount() {
...
this.setState { x: ... }
}
ComponentDidUpdate(prevProps, prevState) {
...
if (prevState.x !== this.state.x) {
this.setState = { isLoading: false }
}
}
...
<Loader active={this.state.isLoading} />
Upvotes: 2
Reputation: 989
you can try this one, this is will set your state after several second:
import React, { Component } from 'react';
import logo from './logo.svg';
class App extends React.Component
{
constructor()
{
super();
this.state = {isLoading: true}
console.log(this.state.isLoading);
}
componentDidMount()
{
setTimeout(() => this.setState({isLoading: false}), 3000)
console.log("componentDidMount");
}
render()
{
if(this.state.isLoading){
return(
<div><img src={logo} className="App-logo" alt="logo" /></div>
)
}
return(
<div> yourPage </div>
)
}
}
export default App;
this is the simple one if you just to see your loader (using timer), if you want to implement that after getting the API, you can call your API first in componentDidMount
or componentWillMount
after you have response from API you can set your state to false.
in that code i implement the interval is same with your time to get response from your API. if you want to get data from API, this is the example code :
import React, { Component } from 'react';
import logo from './logo.svg';
class App extends React.Component
{
constructor()
{
super();
this.state = {isLoading: true}
console.log(this.state.isLoading);
}
componentWillMount() {
fetchAPI()
.then((response) => {
this.setState({isLoading: false})
})
.catch((error) => {
console.log('error = ', error)
}
}
render()
{
if(this.state.isLoading){
return(
<div><img src={logo} className="App-logo" alt="logo" /></div>
)
}
return(
<div> yourPage </div>
)
}
}
export default App;
Hope it can help you, Thanks :)
Upvotes: 1
Reputation: 10227
You set isLoading
state to false
right after component did mount. It immediately re-renders and shows yourPage
respectively (re-render takes just milliseconds).
If you want to set loader before your React app has been loaded, you need to set it directly in your index html
file. For example, you have:
<body>
<div id='root'> // In here you insert your React App component
// Insert your loader down here
// It will immediately disappear after React App is inserted
// (You should use vanilla HTML + CSS - not ReactJS of course)
// Example:
<style>
.my-app-loader {
// css styles
}
</style>
<div class='my-app-loader'></div>
</div>
</body>
If you want to show loader while waiting for server API response, then you should change isLoading
state according to request status. For example:
class App extends React.Component {
...
componentWillMount() {
fetchSomeDataFromServer()
.then((response) => {
this.setState({isLoading: false})
// Do what you need with that response data
})
.catch((error) => {
// Handle error
}
}
...
}
export default App
Upvotes: 1