I am working in react and try to build a page for this web app that displays data.
I haven't even been able to get it to display the data for this page yet.
The code that I need to pull is from a web link, I need to pull that and display it on a card with material UI.
import React, { Component } from 'react';
import Card from '#material-ui/core/Card';
import CardContent from '#material-ui/core/CardContent';
import Paper from '#material-ui/core/Paper';
import Typography from '#material-ui/core/Typography';
import PropTypes from 'prop-types';
import { withStyles } from '#material-ui/core/styles';
const STYLES = {
card: {
minWidth: 275,
},
//bullet: {
//display: 'inline-block',
//margin: '0 2px',
//transform: 'scale(0.8)',
//},
//title: {
//marginBottom: 16,
//fontSize: 14,
//},
//pos: {
// marginBottom: 12,
//},
};
class ErrorView extends Component{
constructor(props) {
super(props);
this.extractErrorData = this.extractErrorData.bind(this)
}
extractErrorData(errorDatas) {
return errorDatas.map((errorViewData) => {
<Card>
<CardContent>
{'errorData.project'}
</CardContent>
<CardContent>
{'errorData.errorText'}
</CardContent>
</Card>
})
}
render() {
const { header, errorViewData } = this.props;
return (
<Paper elevation={4} Color='#fff'>
<Typography variant="headline" component="h3">
{header}
</Typography>
{this.extractErrorData(errorViewData)}
</Paper>
);
}
}
ErrorView = {
classes: PropTypes.object.isRequired,
};
export default withStyles(STYLES)(ErrorView);
Remove the single quotes in extractErrorData if you want to show errorData.project and errorData.errorText values (and rename errorData with errorViewData):
extractErrorData(errorDatas) {
return errorDatas.map((errorViewData) => {
<Card>
<CardContent>
{errorViewData.project}
</CardContent>
<CardContent>
{errorViewData.errorText}
</CardContent>
</Card>
})
}
Note: you should add a JSFiddle or write something more to let us better understand what the problem is.
Related
I'm in the process of building out a simple react act that display REST data from my localhost URL.
I keep getting this error and I'm not sure why, at first I thought it was the data within the API itself but I think that's not the case for this?
I am not getting any npm start errors, the error appears when I inspect a page with browser tools.
Here is the full error:
index.js:1 Warning: Encountered two children with the same key, `1`. Keys should be unique so that components maintain their identity across updates. Non-unique keys may cause children to be duplicated and/or omitted — the behavior is unsupported and could change in a future version.
at div
at Grid (http://localhost:4000/static/js/0.chunk.js:1556:35)
at WithStyles(ForwardRef(Grid)) (http://localhost:4000/static/js/0.chunk.js:6385:31)
at main
at Container (http://localhost:4000/static/js/0.chunk.js:1101:23)
at WithStyles(ForwardRef(Container)) (http://localhost:4000/static/js/0.chunk.js:6385:31)
at UserBuckets (http://localhost:4000/static/js/main.chunk.js:363:5)
at LoadingComponent (http://localhost:4000/static/js/main.chunk.js:999:5)
at div
at App (http://localhost:4000/static/js/main.chunk.js:173:89)
at Route (http://localhost:4000/static/js/0.chunk.js:48473:29)
at Switch (http://localhost:4000/static/js/0.chunk.js:48675:29)
at Router (http://localhost:4000/static/js/0.chunk.js:48108:30)
at BrowserRouter (http://localhost:4000/static/js/0.chunk.js:47728:35)
Could someone point out what is causing this error in my code? I haven't been able to solve it myself.
Here is my required code:
App.js
import React, { useEffect, useState } from 'react';
import './App.css';
import UserBuckets from './components/BucketLists';
import LoadingComponent from './components/Loading';
function App() {
const ListLoading = LoadingComponent(UserBuckets);
const [appState, setAppState] = useState({
loading: false,
buckets: null,
});
useEffect(() => {
setAppState({ loading: true });
const apiUrl = `http://127.0.0.1:8000/api/`;
fetch(apiUrl)
.then((data) => data.json())
.then((buckets) => {
setAppState({ loading: false, buckets: buckets });
});
}, [setAppState]);
return (
<div className="App">
<h1>Latest Buckets</h1>
<ListLoading isLoading={appState.loading} buckets={appState.buckets} />
</div>
);
}
export default App;
bucketList.js
import React from 'react';
import { makeStyles } from '#material-ui/core/styles';
import Card from '#material-ui/core/Card';
import CardContent from '#material-ui/core/CardContent';
import CardMedia from '#material-ui/core/CardMedia';
import Grid from '#material-ui/core/Grid';
import Typography from '#material-ui/core/Typography';
import Container from '#material-ui/core/Container';
const useStyles = makeStyles((theme) => ({
cardMedia: {
paddingTop: '56.25%', // 16:9
},
link: {
margin: theme.spacing(1, 1.5),
},
cardHeader: {
backgroundColor:
theme.palette.type === 'light'
? theme.palette.grey[200]
: theme.palette.grey[700],
},
bucketTitle: {
fontSize: '16px',
textAlign: 'left',
},
bucketText: {
display: 'flex',
justifyContent: 'left',
alignItems: 'baseline',
fontSize: '12px',
textAlign: 'left',
marginBottom: theme.spacing(2),
},
}));
const UserBuckets = (props) => {
const { buckets } = props;
const classes = useStyles();
if (!buckets || buckets.length === 0) return <p>Can not find any buckets, sorry</p>;
return (
<React.Fragment>
<Container maxWidth="md" component="main">
<Grid container spacing={5} alignItems="flex-end">
{buckets.map((buckets) => {
return (
// Enterprise card is full width at sm breakpoint
<Grid item key={buckets.owner} xs={12} md={4}>
<Card className={classes.card}>
<CardMedia
className={classes.cardMedia}
image="https://source.unsplash.com/random"
title="Image title"
/>
<CardContent className={classes.cardContent}>
<Typography
gutterBottom
variant="h6"
component="h2"
className={classes.bucketTitle}
>
{buckets.name.substr(0, 50)}...
</Typography>
<div className={classes.bucketText}>
<Typography
component="p"
color="textPrimary"
></Typography>
<Typography variant="p" color="textSecondary">
{buckets.stock_list}...
</Typography>
</div>
</CardContent>
</Card>
</Grid>
);
})}
</Grid>
</Container>
</React.Fragment>
);
};
export default UserBuckets;
Loading.js
import React from 'react';
function LoadingComponent(Component) {
return function LoadingComponent({ isLoading, ...props }) {
if (!isLoading) return <Component {...props} />;
return (
<p style={{ fontSize: '25px' }}>
We are waiting for the data to load!...
</p>
);
};
}
export default LoadingComponent;
Thank in advance...
The error came from this culprit and my mistake not seeing the important of the letter key in item key. This is how I solved my error:
original code
<Grid item key={buckets.owner} xs={12} md={4}>
fixed code
<Grid item key={buckets.id} xs={12} md={4}>
So I am making a react app, and I think it's better to show you the code than explain:
Body.js:
import React from 'react';
import Clearsky from "Images/clearsky.jpg";
import Rain from "Images/clearsky.jpg";
import Cloudy from "Images/clearsky.jpg";
const type = {
CLEARSKY: "clearsky",
RAIN: "rain",
CLOUDY: "cloudy"
}
class LeftSide extends React.Component {
constructor(props) {
super(props);
this.state = {
type: this.props.type,
degrees: this.props.degrees
}
}
render() {
return (
""
);
}
}
export default function Body() {
//This is printing the correct path and if I type it in the browser I can see the image.
console.log(type.CLEARSKY);
const style = {
//Not working
backgroundImage: `url(${Clearsky})`
}
return (
<div className="body" style={style}>
<LeftSide />
</div>
);
}
Header.js (uses material-ui.com):
import React from 'react';
import { makeStyles } from '#material-ui/core/styles';
import AppBar from '#material-ui/core/AppBar';
import Toolbar from '#material-ui/core/Toolbar';
import Typography from '#material-ui/core/Typography';
import IconButton from '#material-ui/core/IconButton';
import MenuIcon from '#material-ui/icons/Menu';
import logo from "Images/icon.png";
const useStyles = makeStyles((theme) => ({
root: {
flexGrow: 1,
},
menuButton: {
marginRight: theme.spacing(2),
},
title: {
flexGrow: 1,
},
}));
export default function Header() {
const classes = useStyles();
return (
<div className={classes.root}>
<AppBar position="fixed" style={{ borderRadius: "25px"}}>
<Toolbar>
<IconButton edge="start" className={classes.menuButton} color="inherit" aria-label="menu">
<MenuIcon />
</IconButton>
<Typography variant="h6" className={classes.title}>
Weather
</Typography>
<img src={logo} alt="Icon" height="50" width="50" />
</Toolbar>
</AppBar>
</div>
);
}
index.js:
import React from "react";
import ReactDOM from "react-dom";
import Header from "./Header.js";
import Body from "./Body.js";
export default function App() {
return (
<div className="App">
<Header />
<Body />
</div>
);
}
ReactDOM.render(<App />, document.getElementById("root"));
However the backgroundImage on Body.js is not working, just the default white background.
Tried:
Image from an online server (not a local image).
Setting backgroundSize.
EDIT:
My directory:
src:
Images:
EDIT 2:
I have noticed that if I change the LeftSide component to return
<p>A</p>
Instead of "" it will render this in the browser:
Part of the image has been rendered.
Now I believe it is something with the css.
Solved by adding the following css:
const style = {
//Now working
backgroundImage: `url(${Clearsky})`,
height: "100vh",
backgroundSize: "cover",
}
The issue was the height and the size.
I believe your code is correct, but the div with the background has no width and height enough to be visible. Please check if this is the case.
Working sample (see lines 31 and 32): https://codesandbox.io/s/holy-pine-wpdw7
I am trying to make a react component to display a notification on use.
The thing is that it's not working correctly...
The notification is supposed to appear when a user logs-in with an email with wrong provider
what am I doing is that I check for user email after he logs in if the mail doesn't contain the right provider I log him out.
what is happening is that the notification is showing up and disappearing quickly after logging the user out though I made a long interval for it.
I tried experimenting with material UI the react UI framework.
Nothing is working so far
Navbar.js
import React, { Component } from "react";
import withFirebaseAuth from "react-with-firebase-auth";
import * as firebase from "firebase/app";
import firebaseConfig from "../../firebase.config";
import "firebase/auth";
// Material UI
import { makeStyles } from "#material-ui/core/styles";
import AppBar from "#material-ui/core/AppBar";
import Toolbar from "#material-ui/core/Toolbar";
import Typography from "#material-ui/core/Typography";
import Button from "#material-ui/core/Button";
import IconButton from "#material-ui/core/IconButton";
import MenuIcon from "#material-ui/icons/Menu";
import AccountCircle from "#material-ui/icons/AccountCircle";
import Tooltip from "#material-ui/core/Tooltip";
import Notify from "../notification/notification"
const firebaseApp = firebase.initializeApp(firebaseConfig);
const useStyles = makeStyles(theme => ({
root: {
flexGrow: 1
},
menuButton: {
marginRight: theme.spacing(2)
},
title: {
flexGrow: 1
}
}));
const filler = () => {console.log(' ')}
function HomeNav(props) {
const { user, signOut, signInWithGoogle } = props;
const classes = useStyles();
const userMail = (user)?user.email.includes("#hijrah.org"):'';
let notify = false;
if(user && !userMail){
signOut();
notify = true;
}
return (
<div className={classes.root}>
<AppBar position="static">
<Toolbar>
<IconButton
edge="start"
className={classes.menuButton}
color="inherit"
aria-label="menu"
>
<MenuIcon />
</IconButton>
<Typography variant="h6" className={classes.title}>
News
</Typography>
{user? (
<Tooltip title={user.displayName}>
<IconButton
edge="end"
aria-label="account of current user"
aria-haspopup="true"
onClick={signOut}
color="inherit"
>
<AccountCircle />
</IconButton>
</Tooltip>
) : (
<Button color="inherit" onClick={signInWithGoogle}>
Login
</Button>
)}
</Toolbar>
</AppBar>
<React.Fragment>
{/*this is the part where i try to display notification on*/}
{(notify)? <Notify /> : <span></span>}
</React.Fragment>
</div>
);
}
class Nav extends Component {
render() {
return <HomeNav {...this.props} />;
}
}
const firebaseAppAuth = firebaseApp.auth();
const providers = {
googleProvider: new firebase.auth.GoogleAuthProvider()
};
providers.googleProvider.setCustomParameters({hd:"hijrah.org"});
export default withFirebaseAuth({
providers,
firebaseAppAuth
})(Nav);
my notification component notify.js
import React from "react";
import PropTypes from "prop-types";
import clsx from "clsx";
import CheckCircleIcon from "#material-ui/icons/CheckCircle";
import ErrorIcon from "#material-ui/icons/Error";
import InfoIcon from "#material-ui/icons/Info";
import CloseIcon from "#material-ui/icons/Close";
import { amber, green } from "#material-ui/core/colors";
import IconButton from "#material-ui/core/IconButton";
import Snackbar from "#material-ui/core/Snackbar";
import SnackbarContent from "#material-ui/core/SnackbarContent";
import WarningIcon from "#material-ui/icons/Warning";
import { makeStyles } from "#material-ui/core/styles";
const variantIcon = {
success: CheckCircleIcon,
warning: WarningIcon,
error: ErrorIcon,
info: InfoIcon
};
const useStyles1 = makeStyles(theme => ({
success: {
backgroundColor: green[600]
},
error: {
backgroundColor: theme.palette.error.dark
},
info: {
backgroundColor: theme.palette.primary.main
},
warning: {
backgroundColor: amber[700]
},
icon: {
fontSize: 20
},
iconVariant: {
opacity: 0.9,
marginRight: theme.spacing(1)
},
message: {
display: "flex",
alignItems: "center"
}
}));
function MySnackbarContentWrapper(props) {
const classes = useStyles1();
const { className, message, onClose, variant, ...other } = props;
const Icon = variantIcon[variant];
return (
<SnackbarContent
className={clsx(classes[variant], className)}
aria-describedby="client-snackbar"
message={
<span id="client-snackbar" className={classes.message}>
<Icon className={clsx(classes.icon, classes.iconVariant)} />
{message}
</span>
}
action={[
<IconButton
key="close"
aria-label="close"
color="inherit"
onClick={onClose}
>
<CloseIcon className={classes.icon} />
</IconButton>
]}
{...other}
/>
);
}
MySnackbarContentWrapper.propTypes = {
className: PropTypes.string,
message: PropTypes.string,
onClose: PropTypes.func,
variant: PropTypes.oneOf(["error", "info", "success", "warning"]).isRequired
};
export default function CustomizedSnackbars() {
const [open, setOpen] = React.useState(true);
const handleClose = (event, reason) => {
if (reason === "clickaway") {
return;
}
setOpen(false);
};
return (
<div>
<Snackbar
anchorOrigin={{
vertical: "bottom",
horizontal: "left"
}}
open={open}
autoHideDuration={60000}
onClose={handleClose}
>
<MySnackbarContentWrapper
onClose={handleClose}
variant="warning"
message="Please login with a #hijrah.org mail"
/>
</Snackbar>
</div>
);
}
I expect to display the error message after I log out the user and for it to stay for like 5 seconds.
I suspect what is happening in that when you log the user out, the Nav component is no longer rendered and therefore neither is the Notify Component as it is a child of Nav (Nav >> HomeNav >> Notify). Because it is no longer rendered the message disappears.
If that is the case, you should move the Notify to a higher level in your app so that it is displayed regardless of whether the user is logged in or not.
Dear community I am currently writing a website and its user onboarding using the ProrgressiveMobileStepper using Material UI. You can find my website here:
https://konekto-eeioq6hwh.now.sh/first_use
Apart from the formatting being screwed up (for which I would also appreciate your help), I am mainly concerned that the next button does not work. I have structured that the several screens are conditionally rendered in index.js depending on the state and the handleNext function should be called from ProgressiveMobileStepper when the button is clicked. However, the screen does not update then.
index.js file:
import React from 'react';
import { Grid, Container } from '#material-ui/core';
import { Header } from '../Layout';
import logo from './android-icon-192x192.png';
import { withStyles } from '#material-ui/core/styles';
import ExplanationAboutProcess0 from './Explanation0';
import ExplanationAboutProcess1 from './ExplanationProcess1';
import ExplanationAboutProcess2 from './ExplanationProcess2';
import ExplanationAboutProcess3 from './ExplanationProcess3';
import ProgressiveMobileStepper from './ProgressiveMobileStepper';
const styles = theme => ({
container: {
alignItems: 'center',
border: 'black',
'border-width': 'medium',
'margin-top': '80px',
background: 'rgba(255, 255, 255, 0.8)',
'border-radius': '20px'
},
picture: { display: 'block', margin: '0 auto' },
box: { width: '230px' }
});
class FirstUse extends React.Component {
constructor(props) {
super(props);
this.classes = props.classes;
this.state = {
componentType: 'explanationaboutprocess0'
};
this.handleNext = this.handleNext.bind(this);
this.handleBack = this.handleBack.bind(this);
}
fun() {
//this.props.history.push('/settings');
}
handleNext(e) {
console.log(e);
console.log(this.componentType);
if (this.componentType == 'explanationaboutprocess0')
this.setState({ componentType: 'explanationaboutprocess1' });
}
handleBack(e) {
console.log(e);
if (this.componentType == 'explanationaboutprocess1')
this.setState({ componentType: 'explanationaboutprocess0' });
}
render() {
let component;
if (this.state.componentType == 'explanationaboutprocess0') {
component = (
<ExplanationAboutProcess0
handleNext={this.handleNext}
handleBack={this.handleBack}
/>
);
} else if (this.state.componentType == 'explanationaboutprocess1') {
component = (
<ExplanationAboutProcess1
handleComponentType={this.handleComponentType}
handleBack={this.handleBack}
/>
);
} else if (this.state.componentType == 'explanationaboutprocess2') {
component = (
<ExplanationAboutProcess2
handleComponentType={this.handleComponentType}
handleBack={this.handleBack}
/>
);
} else if (this.state.componentType == 'explanationaboutprocess3') {
component = (
<ExplanationAboutProcess3
handleComponentType={this.handleComponentType}
handleBack={this.handleBack}
/>
);
}
return (
<React.Fragment>
<Header title="Learn how to send SOS" />
<Grid
container
className={this.classes.container}
direction="column"
spacing={2}
>
<Grid item sm={12} className={this.classes.item}>
<img src={logo} alt="Logo" />
</Grid>
<Grid item sm={12} className={this.classes.item} />
<Container component="main" maxWidth="sm">
{component}
</Container>
</Grid>
<Grid item sm={12} className={this.classes.item}>
<ProgressiveMobileStepper />
</Grid>
</React.Fragment>
);
}
}
export default withStyles(styles)(FirstUse);
ProgressiveMobileStepper.js file:
import React from 'react';
import { makeStyles, useTheme } from '#material-ui/core/styles';
import MobileStepper from '#material-ui/core/MobileStepper';
import Button from '#material-ui/core/Button';
import KeyboardArrowLeft from '#material-ui/icons/KeyboardArrowLeft';
import KeyboardArrowRight from '#material-ui/icons/KeyboardArrowRight';
const useStyles = makeStyles({
root: {
maxWidth: 400,
flexGrow: 1
}
});
export default function ProgressMobileStepper(props) {
const classes = useStyles();
const theme = useTheme();
const [activeStep, setActiveStep] = React.useState(0);
return (
<MobileStepper
variant="progress"
steps={6}
position="static"
className={classes.root}
nextButton={
<Button
size="small"
onClick={props.handleNext}
disabled={activeStep === 5}
>
Next
{theme.direction === 'rtl' ? (
<KeyboardArrowLeft />
) : (
<KeyboardArrowRight />
)}
</Button>
}
backButton={
<Button
size="small"
onClick={props.handleBack}
disabled={activeStep === 0}
>
{theme.direction === 'rtl' ? (
<KeyboardArrowRight />
) : (
<KeyboardArrowLeft />
)}
Back }
</Button>
}
/>
);
}
Just as an example, you can see two of the screens, which should be conditionally rendered below:
Explanation0.js file:
import React from 'react';
import { Typography } from '#material-ui/core';
export default class ExplanationAboutProcess1 extends React.Component {
constructor(props) {
super(props);
this.classes = props.classes;
this.state = {};
}
render() {
return (
<React.Fragment>
<Typography>
Konnekto allows you to send an emergency request from you phone
without requiring a celluar connection. Please enter your personal
information.
</Typography>
</React.Fragment>
);
}
}
ExplanationProcess1.js file:
import React from 'react';
export default class ExplanationAboutProcess1 extends React.Component {
constructor(props) {
super(props);
this.classes = props.classes;
this.state = {};
}
render() {
return (
<React.Fragment>
<p>
To explain you how you would use the app in case of emergency, we
guide you through which questions we ask you:
<br />
0.1 Are you affected yourself?
<br />
0.2 How do you want to contact?
</p>
</React.Fragment>
);
}
}
I would really appreciate your help!
I have an App Bar component, I'm using Material UI v1.0.0-beta.33
import React from "react";
import PropTypes from "prop-types";
import { withStyles } from "material-ui/styles";
import AppBar from "material-ui/AppBar";
import Toolbar from "material-ui/Toolbar";
import Typography from "material-ui/Typography";
import Button from "material-ui/Button";
import IconButton from "material-ui/IconButton";
import MenuIcon from "material-ui-icons/Menu";
import TemporaryDrawer from "./Drawer";
const styles = {
root: {
width: "100%"
},
flex: {
flex: 1
},
menuButton: {
marginLeft: -12,
marginRight: 20
},
};
function ButtonAppBar(props) {
const { classes } = props;
return (
<div className={classes.root}>
<TemporaryDrawer/>
<AppBar position="static">
<Toolbar>
<IconButton className={classes.menuButton} color="inherit" aria-label="Menu">
<MenuIcon />
</IconButton>
<Typography variant="title" color="inherit" className={classes.flex}>
Title
</Typography>
<Button onClick={} color="inherit">User Name</Button>
</Toolbar>
</AppBar>
</div>
);
}
ButtonAppBar.propTypes = {
classes: PropTypes.object.isRequired
};
export default withStyles(styles)(ButtonAppBar);
As you can see I'm importing another component called TemporaryDrawer, in the code of that component there's a method called "toggleDrawer" that triggers the Drawer.
My questions is how can I use the toggleDrawer method from TemporaryDrawer in the above code, I have a button with the onClick method empty.
For reference, I put the code from TemporaryDrawer below:
import React from "react";
import PropTypes from "prop-types";
import { withStyles } from "material-ui/styles";
import Drawer from "material-ui/Drawer";
import List from "material-ui/List";
import Divider from "material-ui/Divider";
const styles = {
list: {
width: 250
},
listFull: {
width: "auto"
}
};
class TemporaryDrawer extends React.Component {
state = {
left: false
};
toggleDrawer = (side, open) => () => {
this.setState({
[side]: open
});
};
render() {
const { classes } = this.props;
const sideList = (
<div className={classes.list}>
<List>AA</List>
<List>BB</List>
<List>CC</List>
<Divider />
<List>AA1</List>
<List>BB1</List>
<List>CB1</List>
</div>
);
return (
<div>
<Drawer open={this.state.left} onClose={this.toggleDrawer("left", false)}>
<div
tabIndex={0}
role="button"
onClick={this.toggleDrawer("left", false)}
onKeyDown={this.toggleDrawer("left", false)}
>
{sideList}
</div>
</Drawer>
</div>
);
}
}
TemporaryDrawer.propTypes = {
classes: PropTypes.object.isRequired,
};
export default withStyles(styles)(TemporaryDrawer);
Thanks in advance.
Looking at the toggleDrawer method in TemporaryDrawer component
the method can simply be "litfed" into the parent component ButtonAppBar
updated ButtonAppBar turned in the class component:
class ButtonAppBar extends Component {
constructor(props) {
super(props);
this.state {
isDrawerOpen: false
}
this.closeDrawer = this.closeDrawer.bind(this);
}
closeDrawer() {
this.setState({ isDrawerOpen: false });
}
render() {
const { classes } = props;
return (
<div className={classes.root}>
<TemporaryDrawer open={this.state.isDrawerOpen} onDrawerClose={this.closeDrawer} />
<AppBar position="static">
<Toolbar>
<IconButton className={classes.menuButton} color="inherit" aria-label="Menu">
<MenuIcon />
</IconButton>
<Typography variant="title" color="inherit" className={classes.flex}></Typography>
<Button onClick={} color="inherit">User Name</Button>
</Toolbar>
</AppBar>
</div>
);
}
}
And then TemporaryDrawer component can be:
class TemporaryDrawer extends Component {
constructor(props) {
super(props);
}
render() {
return (
<Drawer open={this.props.isDrawerOpen} onClose={this.props.onDrawerClose}>
...
</Drawer>
)
}
}