Reactjs - render child asynchronous - asynchronous

I am showing loading gif, until canvas is fully rendered, i make then callback to set visible of loading gif to off. But all time during rendering, gif rotating is stopped and other parts of page doesn't react too. So is there any way ho to render any component asynchronous to prevent influencing with other parts of page?
class GraphPage extends React.Component {
constructor(props) {
super(props);
this.state = {
loaded: false,
print: null,
loading: true
}
}
componentDidMount(){
this.setReady();
}
render(){
const graphList = graphStore.getGraphValue();
var {data} = this.props;
return(
<div>
<div className="inputs">
<Inputs modal={false} unit='%' list={graphList.rotation} descTitle={data.graph.machine}/>
<Inputs modal={false} unit='mm' list={graphList.machine} descTitle={data.graph.rotation}/>
</div>
<div className="graph">
{this.state.loading? <img src={loadingIcon}/> : false}
{this.state.print? <Print readyToRender={this.update.bind(this)}/> : false}
</div>
</div>
)
}
update(){
this.setState({
loading: false
})
}
setReady(){
setTimeout(function() {
this.setState({print: new Print()})
}.bind(this), 1000);
}
}

I would put the rotating gif in the renderer of Print.
class Print extends React.Component {
constructor(props) {
super(props);
this.state = {
renderFinished: true
}
this.calculate().then(function() {
/* Canvas done => display it! */
this.setState({ renderFinished: true })
}.bind(this))
calculate() {
var result = new Promise();
// Something asyncronous, just an example
setTimeout(function(){
while(doCalc) {
if(calcIsDone) {
// Ready for render
result.resolve(theResult);
}
}
}.bind(this), 0);
return result;
}
render() {
return {
renderFinished ?
<div>
{ /* Here goes the rendered canvas output */ }
</div>
:
<img src={loadingIcon}/>
}
};
}
And then GraphPage looks like this
class GraphPage extends React.Component {
constructor(props) {
super(props);
}
render(){
// It look like graphStore is globally available so Print also can access it directly
const graphList = graphStore.getGraphValue();
var {data} = this.props;
return(
<div>
<div className="inputs">
<Inputs modal={false} unit='%' list={graphList.rotation} descTitle={data.graph.machine}/>
<Inputs modal={false} unit='mm' list={graphList.machine} descTitle={data.graph.rotation}/>
</div>
<div className="graph">
{ /* Maybe graphStore should be given here as a prop? */ }
<Print/>
</div>
</div>
)
}
}

Related

How can I create horizontal and vertical animation slider using react-stack-cards in ReactJs?

import React, { Component } from 'react'
import { ToggleCard, TinderLikeCard, StackCard } from 'react-stack-cards'
class Card extends React.Component {
constructor(props) {
super(props)
this.state = {
directionTinder: "swipeCornerDownRight",
directionToggle: "sideSlide",
directionStack: "topRight",
isOpen: false
}
this.Tinder = null
}
onTinderSwipe() {
this.Tinder.swipe()
}
onToggle() {
this.setState({ isOpen: !this.state.isOpen })
}
render() {
const {index, pic, name}=this.props.property
return (
<div className={`card-${index}`}>
<h1>{index}</h1>
<TinderLikeCard
images={pic}
width="550"
height="450"
direction={this.state.directionTinder}
duration={400}
ref={(node) => this.Tinder = node}
className="tinder"
>
</TinderLikeCard>
<button onClick={this.onTinderSwipe.bind(this)}>Swipe</button>
<h1>{name}</h1>
</div>
);
}
}
export default Card

how to reload page after handle state?

My sidebar in the responsive mode not working correctly, i'm use #media for controller width of page, when is responsive i use position:absolute for sidebar button stay in up of content, i created a state for onclick is active change this position:relative but is not working, help please. The page in the mode normal funciton correctly, and mode responsive (Ctrl + shift + I) too but i click in the button the problemn happens.
Sidebar.js
export default class Menu extends Component {
constructor(props) {
super(props);
this.state = {
classStyle: "sidebar"
};
}
// handleSidebar(value) {
// this.setState = ({ classStyle : value });
// }
handleSidebar = (value) => {
this.setState = ({ classStyle: value });
}
render() {
return (
<div className={this.state.classStyle}>
<Navbar bg="light" variant="light" sticky="top" expand="lg">
<Navbar.Toggle aria-controls="navbarSupportedContent" onClick={() => handleSidebar("sidebarR")} />
<Navbar.Collapse id="navbarSupportedContent">
Index.css
#media (max-width: 600px)
{
.sidebar
{
position: absolute;
}
.sidebarR
{
position: relative;
}
}
Please try this one, it is working
Replace this function in your component
handleSidebar = () => {
console.log("clicked");
this.setState({ classStyle: "sidebarR" });
}
If you want toggle class then use below function,
handleSidebar = () => {
console.log("clicked");
const classStyle = this.state.classStyle == "sidebar" ? "sidebarR" : "sidebar";
this.setState({ classStyle: classStyle });
}
Running Component without Navbar Component,
import React,{Component} from 'react';
import './Menu.css';
export default class Menu extends Component {
state = {
classStyle: "sidebar"
};
handleSidebar = () => {
console.log("clicked");
this.setState({ classStyle: "sidebarR" });
}
render() {
return (
<div className={this.state.classStyle}>
<p onClick={() => this.handleSidebar()} >Menu</p>
</div>
)
}
}
When you call handleSidebar on onClick, you need to use this
Navbar.Toggle aria-controls="navbarSupportedContent" onClick={() => this.handleSidebar("sidebarR")} />

React modal is not showing in the center of the screen

With the help of the community, I have been able to final have my modal pop-up working on my reat website.
The modal code is as below:
import React from "react";
import '../../assets/styles/GenericTheme.css'
import { Modal, Button } from "react-bootstrap";
class LoginRegisterModal extends React.Component {
constructor(props, context) {
super(props);
this.state = {show: false};
}
open = () => {
this.setState({show: true});
}
close = () => {
this.setState({show: false});
}
componentDidUpdate(prevProps) {
const { show } = this.props;
if (prevProps.show !== show) {
if (show) {
this.open(); // open if parent says to
} else {
this.close(); // close if parent says to
}
}
}
render() {
const styleModal = {
width:770,
height:480,
backgroundColor:"#ffffffff",
borderRadius:21.5,
boxShadow: "0px 8px 18px 0 rgba(0,0,0,0.14)",
}
return (
<Modal show={this.state.show} style={styleModal} >
<Modal.Body>test</Modal.Body>
<Modal.Footer>
<Button variant="secondary" onClick={this.close}>
Close
</Button>
</Modal.Footer>
</Modal>
);
}
}
export default LoginRegisterModal;
The modal is called by the react-bootstrap Navs components:
const menuLoginRegister = <Nav.Link ref="LoginRegisterModal" eventKey={1} href="#" onClick={this.openLogin}>{TextContents.MenuLoginRegister}</Nav.Link>;
And I have added the modal in the return function like below:
return (
<div>
<Navbar className="village-header" width="100" expand="lg">
....
</Navbar>
<LoginRegisterModal show={this.state.showLogin}
onHide={() => this.setState({ showLogin: false })}/>
</div>
);
The only issues is that the modal keep being displayed on the top left corner and not centered in the screen.
I tried to use a center in the style but it still not move it to the center.
Any idea how to do it ?
Thanks

SetState doesn't update when button is clicked

I'm trying to change the color at the button click using setState. But it doesn't change the state when the button is clicked. I have attached my App.js and Index.html files.
It works when I try it on Visual studio code. but it doesn't work in visual studio 2019 with asp.net mvc. I want to try it with Asp.net mvc with reactjs intergrated project
class Business extends React.Component {
constructor(props) {
super(props);
this.state = {color: "red" };
}
changeColor = () => {
this.setState({ color: "blue" });
}
render() {
return (
<div>
<h1>My Favorite Color is {this.state.color}</h1>
<button type="button" onClick={this.changeColor}>Change Color</button>
</div>
);
}
}
#using React.Web.Mvc
#{
ViewBag.Title = "Index";
}
<h2>Index</h2>
#Html.React("Business", new
{
})
Please update your code with as below:
class Business extends React.Component {
constructor(props) {
super(props);
this.state = {
color: "red"
};
}
changeColor = () => {
/*Please remove alert*/
alert('Working');
this.setState({ color: "blue" });
}
render() {
return (
<div>
<h1>
My Favorite Color is {this.state.color}
</h1>
<button type="button" onClick={this.changeColor}>Change Color</button>
</div>
);
}
}
export default Business;

Layer over complete page not displaying correctly

I have an issue in my react application. I'm using styled-components for using styling (CSS-in-JS).
The issue:
When the user performs a specific action, a layer over the complete page should be displayed. I've created for this an seperate component. But the layer is not working as expected (see the image). Layer 1 should cover the complete page. Layer 2 should be in the middle of the page.
See my code of the component:
import React, { Component, Fragment } from 'react';
import styled from 'styled-components';
import axios from 'axios';
const uuidv4 = require('uuid/v4');
const RefreshLink = styled.a`
text-decoration: underline;
cursor: pointer;
color: #155724;
&:hover {
color: #155724;
}
`
const Background = styled.div`
position:fixed;
width:100%;
height:100%;
background-color:#aeaeae;
opacity:0.5;
z-index:10000;
`
const PopUp = styled.div`
position:fixed;
z-index:10001;
left:50%;
margin-left:-25%;
width:450px;
top:50%;
margin-top:-25%;
`
class UpdatingFreightsInfo extends Component {
_isMounted = false;
signal = axios.CancelToken.source();
constructor(props) {
super(props);
this.state = {
freightsInUpdateProcess: false,
hasFreightsBeenInUpdateStatusSincePageLoad: false,
intervalId: -1,
freightsUpdating: [],
};
this.checkForUpdatingFreights = this.checkForUpdatingFreights.bind(this);
}
componentDidMount() {
this._isMounted = true;
this.getUpdatingFreightsInfo();
}
componentWillUnmount() {
this.signal.cancel();
clearInterval(this.state.intervalId);
this._isMounted = false;
}
componentDidUpdate(prevProps) {
if (this.props.updateTrigger !== prevProps.updateTrigger) {
this.checkForUpdatingFreights();
}
}
getUpdatingFreightsInfo() {
this.checkForUpdatingFreights();
let intervalId = setInterval(() => {
this.checkForUpdatingFreights();
},30000);
this.setState({
intervalId: intervalId
});
}
checkForUpdatingFreights = async () => {
try {
const response = await axios.get('../data/get/json/freightsCurrentlyUpdating', {
cancelToken: this.signal.token,
})
.then((response) => {
console.log(response);
if(response != undefined && response != null) {
if (this._isMounted) {
if(response.data.length > 0) {
this.setState({
freightsUpdating: response.data,
freightsInUpdateProcess: true,
hasFreightsBeenInUpdateStatusSincePageLoad: true,
});
}
else {
this.setState({
freightsUpdating: [],
freightsInUpdateProcess: false,
});
}
}
}
})
.catch(function (error) {
console.log(error);
});
}
catch(err) {
if (axios.isCancel(err)) {
console.log('Error: ', err.message); // => prints: Api is being canceled
} else {
}
}
}
render() {
return (
(this.state.freightsInUpdateProcess || (this.state.hasFreightsBeenInUpdateStatusSincePageLoad && !this.state.freightsInUpdateProcess )) &&
<Fragment>
<Background key={uuidv4()}></Background>
<PopUp key={uuidv4()}>
<div className="container-fluid">
<div className="row">
<div className="col-12 col-sm-12 col-md-12 col-lg-12">
{
this.state.freightsInUpdateProcess &&
<div className="alert alert-warning text-center" role="alert">
<h4 className="alert-heading">Updating freights in process</h4>
<p className="mb-0">{ this.state.freightsUpdating.length } freight entries are currently being updated.</p>
</div>
}
{
this.state.hasFreightsBeenInUpdateStatusSincePageLoad && !this.state.freightsInUpdateProcess &&
<div className="alert alert-success text-center" role="alert">
<h4 className="alert-heading">Updating freights finished</h4>
<p className="mb-0">
The update process has been finished.
<br />
<span className="fa fa-refresh"></span> <RefreshLink href="/" target="_self">Please refresh the page</RefreshLink>
</p>
</div>
}
</div>
</div>
</div>
</PopUp>
</Fragment>
);
}
}
export default UpdatingFreightsInfo;
Is it because the component is being nested in other components? It seems like that, but I thought, when using CSS
position: fixed with combination of left and top
that this code is independent from the components. And also strange that in PopUp it seems to work (almost) correctly.

Resources