React Progressbar not Visible? - reactjs

I have created a React progress bar with the help of third part library
import React from "react";
import { css } from "#emotion/core";
import ClipLoader from "react-spinners/ClipLoader";
// Can be a string as well. Need to ensure each key-value pair ends with ;
const override = css`
display: block;
margin: 0 auto;
border-color: red;
`;
class AwesomeComponent extends React.Component {
constructor(props) {
super(props);
this.state = {
loading: true
};
}
render() {
return (
<div className="sweet-loading">
<ClipLoader
css={override}
size={150}
color={"#123abc"}
loading={this.state.loading}
/>
</div>
);
}
}
export default AwesomeComponent;
and then import in index.js file
import AwesomeComponent from './awesomeComponent.js';
ReactDOM.render(
<Provider store={store}>
<BrowserRouter>
<App />
<AwesomeComponent />
</BrowserRouter>
</Provider>,
document.getElementById("root")
);
In my application i want to show this progresbar when data loading from nodejs api or any button clicked ..But nothing visible in GUI related to progressbar.

If you are using class based component for react-promise-tracker then you need to use HOC promiseTrackerHoc :
import React from "react";
import { css } from "#emotion/core";
import ClipLoader from "react-spinners/ClipLoader";
import { promiseTrackerHoc } from "react-promise-tracker"; // <--------- HERE
// Can be a string as well. Need to ensure each key-value pair ends with ;
const override = css`
display: block;
margin: 0 auto;
border-color: red;
`;
class AwesomeComponent extends React.Component {
constructor(props) {
super(props);
this.state = {
loading: true
};
}
render() {
return (
this.props.promiseInProgress && // <--------- HERE
<div className="sweet-loading">
<ClipLoader
css={override}
size={150}
color={"#123abc"}
loading={this.state.loading}
/>
</div>
);
}
}
export default promiseTrackerHoc(AwesomeComponent); // <--------- HERE
WORKING DEMO :
Note :
You can checkout DOC, as they have explained everything, I
think you can help you to find out whatever the scenario you want to
implement

In this example, you can see how you can change the visibility of your spinner just changed the local state by clicking on button
https://codesandbox.io/s/modern-monad-4tipc?file=/src/AwesomeComponent.js

Related

React-Beautiful-Dnd Can't Find Draggable Element with Id

I'm trying to replicate the react-beautiful-dnd tutorial step 4: reorder a list. I've copied the code in the tutorial as far as I can see exactly: https://egghead.io/lessons/react-reorder-a-list-with-react-beautiful-dnd
However, when I run react and try to drag the list items, I get errors like: Unable to find draggable element with id: task-1
If I look at the DOM, I can definitely see an element with that id:
I can't figure out what I'm doing wrong. I printed the id to console to check that it's a string, and it is. Thoughts?
INITIAL-DATA.JS
const initialData = {
tasks : {
"task-1" : { id : "task-1", content : "Take out garbage"},
"task-2" : { id : "task-2", content : "Watch show"},
"task-3" : { id : "task-3", content : "Charge phone"},
"task-4" : { id : "task-4", content : "Cook dinner"},
},
columns : {
"column-1" : {
id : "column-1",
title: "To Do",
taskIds : ["task-1", "task-2", "task-3", "task-4"]
}
},
columnOrder : ["column-1"]
};
export default initialData;
INDEX.JS
import React from 'react';
import ReactDOM from 'react-dom';
import initialData from "./initial-data";
import Column from "./column";
import { DragDropContext } from 'react-beautiful-dnd';
class App extends React.Component {
state = initialData;
// Needs to synchronously update our state to reflect the drag-drop result
// The only required DragDrop callback
onDragEnd = result => {
}
render() {
return (
<DragDropContext onDragEnd={this.onDragEnd}>
{
this.state.columnOrder.map( (columnId) => {
const column = this.state.columns[columnId];
const tasks = column.taskIds.map( taskId => this.state.tasks[taskId]);
return <Column key={column.id} column={column} tasks={tasks} />;
})
}
</DragDropContext>
)
}
}
ReactDOM.render(
<App />,
document.getElementById('root')
);
COLUMN.JS
import React from "react";
import styled from "styled-components";
import Task from "./task";
import { Droppable } from 'react-beautiful-dnd';
const Container = styled.div`
margin: 8px;
border: 1px solid lightgrey;
border-radius: 2px;
`;
const Title = styled.h3`
padding: 8px;
margin: 0px;
`;
const TaskList = styled.div`
padding: 8px;
`;
export default class Column extends React.Component {
render() {
return (
// Note: Droppables expect their child to be a function that returns a react component
<Container>
<Title>{this.props.column.title}</Title>
<Droppable droppableId={this.props.column.id}>
{ provided => (
// The droppableProps in the provided object (a react-beautiful-dnd object) need to get provided to the object
// you want to designate as your droppable
// {provided.placeholder} // Needs to be added as a child of the component you designate as the droppable
// ref is an attribute of -components. Returns the dom node of the component
<TaskList
ref={provided.innerRef}
{...provided.droppableProps}
>
{ this.props.tasks.map( (task, index) => <Task key={task.id} task={task} index={index} /> ) }
{provided.placeholder}
</TaskList>
)}
</Droppable>
</Container>
)
}
}
TASK.JS
import React from "react";
import styled from "styled-components";
import { Draggable } from 'react-beautiful-dnd';
const Container = styled.div`
border: 1px solid lightgrey;
border-radius: 2px;
padding: 8px;
margin-bottom: 8px;
background-color: white; /* so don't see through when dragging */
`;
export default class Task extends React.Component {
render() {
console.log(this.props.task.id)
console.log(typeof this.props.task.id)
return (
// Required draggable props are draggableId and index
// Note: Draggables expect their child to be a function that returns a react component
<Draggable draggableId={this.props.task.id} index={this.props.index}>
{ provided => (
// The draggbleProps in the provided object (a react-beautiful-dnd object) need to get provided to the object
// you want to designate as your draggable
// DragHandleProps needs to get applied to the part of that object that you want to use to drag the whole object
// ref is an attribute of -components. Returns the dom node of the component
<Container
ref={provided.innerRef}
{...provided.draggbleProps}
{...provided.dragHandleProps}
>
{ this.props.task.content }
</Container>
)}
</Draggable>
)
}
}
There is just a typo in your code: in task.js change {...provided.draggbleProps} to {...provided.draggableProps}
As seen above, the issue here was the typo. Per your comment below that answer, you could help avoid this in the future by using Typescript. It would have shown you an error in your editor at the typo, and also given you autocomplete.

Managing state when changing backgroundImage

In state I'm setting background image with a photo and I wanted to do 2 buttons, one is changing background image to another photo and another is setting background image back to the first photo.
Here is piece of my code:
\\index.js
import React from "react";
import ReactDOM from "react-dom";
import App from "./App";
import "semantic-ui/dist/semantic.min.css";
import logo1 from "./modules/images/one.jpg";
ReactDOM.render(
<App bgImage={`url(${logo1})`} />,
document.getElementById("root")
);
\\App.js
import React, { Component } from "react";
import "./App.css";
import NavBar from "./modules/NavBar";
import logo1 from "./modules/images/one.jpg";
import logo2 from "./modules/images/night.jpg";
class App extends Component {
constructor(props) {
super(props);
this.state = {
bgImage: props.bgImage //so here I set the backroundImage with logo1, because I want to logo1 to be on the start of application, but when I change to logo2 I want to have that logo2 even when I refresh page ( but when I do it, constructor of App is setting it to the logo1. So maybe, can I save that logo even when the App is reloading to get the latest logo ?
};
}
ChangeToLightMode = e => {
this.setState({
bgImage: `url(${logo1})`
});
};
ChangeToDarkMode = e => {
this.setState({
bgImage: `url(${logo2})`
});
};
render() {
return (
<div
style={{
display: "flex",
minHeight: "100vh",
flexDirection: "column",
backgroundImage: this.state.bgImage,
height: "100%",
width: "100%"
}}
>
<NavBar
ChangeToDarkMode={this.ChangeToDarkMode}
ChangeToLightMode={this.ChangeToLightMode}
/>
);
}
}
export default App;
\\NavBar.js
import React, { Component } from "react";
class NavBar extends Component {
render() {
return (
<div>
<Menu fixed="top" inverted>
<Menu.Menu position="right">
<Menu.Item onClick={this.props.ChangeToDarkMode}>
DarkMode
</Menu.Item>
<Menu.Item onClick={this.props.ChangeToLightMode}>
LightMode
</Menu.Item>
</Menu.Menu>
</Menu>
</div>
);
}
}
So I implemented a way that I can change background photo but when I click for example logo in my application and the constructor of App is called it is setting my bgImage to the first photo even when I had second photo and I know it. But I want only the first photo to be set in constructor in the start of the application, after it I want to have the photo according to which method I use. So should I store somewhere the bgImage state and do something with it in App constructor ?
If the default value for bgImage needs to be determined before App is rendered, then usually you would do this by passing a prop into the component e.g.
<App bgImage={`url(${logo1})`} />
Then in the constructor, you can set this as the default state
class App extends Component {
constructor(props) {
super(props);
this.state = {
bgImage: props.bgImage
};
}
}

How to render a random trajectory animation infinitely, on some interval?

What I would like is to create a code that 'shoots' out some image from the center of the screen to some random trajectory.
Here is the descriptional code I would like to achieve:
class Name extends React.Component{
render(){
return (
<img animation moving from centre to some random trajectory>
after few seconds...
<another img animation (the same one) moving from centre to some other random trajectory>
<do it many more times, until event occurs that will stop it>
);
}
}
I have made components that create interface, and that render an image animation of movement from centre to some random trajectory, but only once. I don't know how to make it repeatedly.
index.js
import React from 'react';
import ReactDOM from 'react-dom';
import "./bootstrap/css/bootstrap.css";
import {CreateEnvironment} from './components/createEnvironment';
import {SheepsStart} from './components/sheepsStart';
class MainComponent extends React.Component {
render(){
return (
<React.Fragment>
<CreateEnvironment />
<SheepsStart />
</React.Fragment>
);
}
}
ReactDOM.render(<MainComponent/>, document.getElementById('root'));
Component CreateEnvironment is irrelevant, it creates 3 drawing divs.
Component SheepsStart:
import React from 'react';
import {CreateSheeps} from './createSheeps';
import sheep from '../images/sheep.png';
export class SheepsStart extends React.Component {
render(){
return (
<React.Fragment>
<CreateSheeps src = {sheep} alt = "Sheep"/>
</React.Fragment>
);
}
}
Styled component, which I needed so I could insert random #keyframes:
import styled from 'styled-components';
import { sheepWantsToEscape } from './KeyFrames';
export const CreateSheeps = styled.img`
width:2.5%;
z-index: 1;
position:absolute;
left:48.75%;
bottom:48.75%;
animation: ${sheepWantsToEscape} 4s;
animation-iteration-count:1;
animation-timing-function:linear;
`
export default CreateSheeps;
Component with #keyframes with random trajectory coordinates.Function createTrajectory calculates coordinates, and returns an array of two.
import styled, { keyframes } from 'styled-components';
import {createTrajectory} from './helperFunction';
let coordinates = createTrajectory();
export const sheepWantsToEscape = keyframes`
0% {
left:48.75%;
bottom:48.75%;
}
100% {
left:${coordinates[0]}%;
bottom:${coordinates[1]}%;
}
This is only an example, if you point out what you've tried out I'll can be more specific:
const base = 100;
class Hello extends React.Component {
state = {
myStyle : {
marginTop: base,
marginLeft: -base,
}
}
plusMinus = () => Math.random() < 0.5 ? -1 : 1;
randomize = () => {
this.setState({
myStyle: {
marginTop: Math.random()*base*this.plusMinus(),
marginBottom: Math.random()*base*this.plusMinus(),
},
});
}
render() {
return <div><img
style={{...this.state.myStyle}} src="https://upload.wikimedia.org/wikipedia/commons/thumb/a/a7/React-icon.svg/200px-React-icon.svg.png" />
<button onClick={this.randomize}>move</button>
</div>;
}
}
ReactDOM.render(
<Hello name="World" />,
document.getElementById('container')
);
https://jsfiddle.net/vya19fz2/

Simple way to conditionally render styled-components and SVG icons

I had a really hard time trying to find a way for a simple action to render user avatar or SVG icon if avatar doesn't exist.
I didn't found any good examples (or maybe I'm just bad at finding simple solutions) and after many days of struggling came up with a solution, but i don't know if what I'm doing is right and will not get me in trouble in future, because I want to do other components with the same pattern and not rework after.
So I'm asking this community if this way for conditional render styled-components and SVG icons is right?
My file where I have all the icons:
Icon.js
import React from "react"
export class Vk extends React.Component {
constructor(props) {
super(props)
}
render() {
return (
<svg {...this.props} height="100" width="100">
<circle cx="50" cy="50" r="40" stroke="black" stroke-width="3" fill="red" />
</svg>
)
}
}
export class Ghost extends React.Component {
constructor(props) {
super(props)
}
render() {
return (
<svg {...this.props} height="100" width="100">
<circle cx="50" cy="50" r="40" stroke="black" stroke-width="3" fill="red" />
Sorry, your browser does not support inline SVG.
</svg>
)
}
}
With {...this.props} i can change how my SVG looks like dinamicly from component where i render them.
Now my file where i want to render avatar
Profile.js
import React from "react"
import styled from 'styled-components'
// Here i import my avatar component
import Avatar from "src/shared/Avatar"
export default class Profile extends React.Component {
constructor(props) {
super(props)
this.state = { showProfileMenu: false}
}
// Some function
openCloseProfileMenu = () => {
this.setState({ showProfileMenu: !this.state.showProfileMenu })
}
render() {
return (
<ImportAvatar onClick={this.openCloseProfileMenu} profile={this.props.profile} size='50px' />
)
}
}
// Here i can style me avatar commponent
const ImportAvatar = styled(Avatar)`
display: flex;
cursor: pointer;
`
And my Avatar component Avatar.js
import React from "react"
//Here i import ONE svg icon
import { Ghost } from "src/shared/Icon"
import styled from 'styled-components'
export default class Avatar extends React.Component {
constructor(props) {
super(props)
}
render() {
// Here i destroy passed to component props, get and use what i need and pass to component what left with ...other
const {
profile,
size,
...other
} = this.props;
// I will render svg or img, but they have common styles, so i place them in one place
const commonStyle =
`border-radius: 50%;
height: ${size};
width: ${size};
box-shadow: 0 0 5px 2px ${profile.color};`
// Here i use common and some specific for img styles
const AvatarImg = styled.img`
${commonStyle}
height: 100%;`
// I can render SVG component like this styled(props => <Ghost {...props} />)
// Here i use common and some specific for svg styles
const AvatarSvg = styled(props => <Ghost {...props} />)`
${commonStyle}
fill: grey;`
// and finally I conditionally render component with passed attr, functions, styles and my own if i want
return (
profile.avatar
? <AvatarImg {...other} src={profile.avatar} alt={profile.nickname} />
: <AvatarSvg {...other} />
)
}
}

React.js router different background image

I want to apply background image for specific component.
I used react-router-dom and my code is below.
[App.js]
import React, { Component } from 'react';
import { BrowserRouter as Router, Route } from 'react-router-dom';
import Login from './components/Login';
import Home from './components/Home';
class App extends Component {
render() {
return (
<Router>
<div>
<Route exact path="/" component={Login} />
<Route path="/home" component={Home} />
</div>
</Router>
);
}
}
export default App;
[Login.js]
import React, { Component } from 'react';
import './Login.css';
class Login extends Component {
render() {
return (
<div>
Login
</div>
);
}
}
export default Login;
[Login.css]
html {
background-color: red;
}
[Home.js]
import React, { Component } from 'react';
import './Home.css';
class Home extends Component {
render() {
return (
<div>
Home
</div>
);
}
}
export default Home;
[Home.css]
html {
background-color: blue;
}
I set the background-color of Login to red and Home to blue.
But not only Login.js but also Home.js's background color is blue.
How can I set the different background color for each components?
Apply styles to class
Assign a class to the outermost div in Login.js
class Login extends Component {
render() {
return (
<div className="login">
Login
</div>
);
}
}
export default Login;
Now apply styles to the classes
.home{
background-color:blue;
}
.login{
background-color:red;
}
If u want to apply background image for full page try this css..
.home {
background: url("image.jpg");
background-size: cover;
background-repeat: no-repeat;
}
Change the css to:
body {
background-color: red !important;
}
The background color property is set to the body tag, not the html tag. The !important will ensure that this style is applied over any other conflicts you may have.
--Edit--
To apply background colors to the individual components, you should add a class to each of the parent div, and style that class directly like so:
Note: Heights have been added to the styles to ensure 100% vertical fill of the browser, as per the OP's request. It is not required otherwise.
Login.js
import React, { Component } from 'react';
import './Login.css';
class Login extends Component {
render() {
return (
<div className="scene_login">
Login
</div>
);
}
}
export default Login;
Login.css
body, html {
height: 100%;
}
.scene_login {
height: 100%;
background-color: red;
}
Home.js
import React, { Component } from 'react';
import './Home.css';
class Home extends Component {
render() {
return (
<div className="scene__home">
Home
</div>
);
}
}
export default Home;
Home.css
body, html {
height: 100%;
}
.scene__home {
height: 100%;
background-color: blue;
}

Resources