useState is not working for material ui functional component(firebase) - javascript

I am trying to make a sign up form where I am using a material ui functional component
I am trying to attach a signup event to the sign up button in "onClick"
now I am trying to pass email and password in useState() and then trying to console.log(email,password) but it returns nothing
console doesn't show errors either
import React, { Component, useState } from 'react';
import {Route,} from "react-router-dom"
import Avatar from '#material-ui/core/Avatar';
import Button from '#material-ui/core/Button';
import CssBaseline from '#material-ui/core/CssBaseline';
import TextField from '#material-ui/core/TextField';
import FormControlLabel from '#material-ui/core/FormControlLabel';
import Checkbox from '#material-ui/core/Checkbox';
import Link from '#material-ui/core/Link';
import Grid from '#material-ui/core/Grid';
import Box from '#material-ui/core/Box';
import LockOutlinedIcon from '#material-ui/icons/LockOutlined';
import Typography from '#material-ui/core/Typography';
import { makeStyles } from '#material-ui/core/styles';
import Container from '#material-ui/core/Container';
import firebase from "firebase"
var Config ={ apiKey:"",
authDomain: "",
databaseURL: "",
projectId: "",
storageBucket: "",
messagingSenderId: "",
appId: ""
}
firebase.initializeApp(Config);
function signup(event){
const{email,password}=this.props;
firebase.auth().createUserWithEmailAndPassword(email,password)
.then((user) => {
// Signed in
// ...
console.log(email,password)
var err = "Welcome "+ user.email;
firebase.database().ref('users/'+user.uid).set({email: user.email,password:user.password});
})
.catch((error) => {
var errorCode = error.code;
var errorMessage = error.message;
// ..
console.log(errorMessage)
});
}
function Copyright() {
return (
<Typography variant="body2" color="textSecondary" align="center">
{'Copyright © '}
<Link color="inherit" href="https://material-ui.com/">
Your Website
</Link>{' '}
{new Date().getFullYear()}
{'.'}
</Typography>
);
}
const useStyles = makeStyles((theme) => ({
paper: {
marginTop: theme.spacing(8),
display: 'flex',
flexDirection: 'column',
alignItems: 'center',
},
avatar: {
margin: theme.spacing(1),
backgroundColor: theme.palette.secondary.main,
},
form: {
width: '100%', // Fix IE 11 issue.
marginTop: theme.spacing(3),
},
submit: {
margin: theme.spacing(3, 0, 2),
},
}));
export default function SignUp(props) {
const [email, setEmail] = useState("");
const [password, setPassword] = useState("");
const classes = useStyles();
return (
<Container component="main" maxWidth="xs">
<CssBaseline />
<div className={classes.paper}>
<Avatar className={classes.avatar}>
<LockOutlinedIcon />
</Avatar>
<Typography component="h1" variant="h5">
Sign up
</Typography>
<form className={classes.form} noValidate>
<Grid container spacing={2}>
<Grid item xs={12} sm={6}>
<input
variant="outlined"
margin="normal"
required
fullWidth
id="email"
label="Email Address"
onChange={(e) => {
setEmail(e.target.value);
console.log(e.target.value)}}
autoComplete="email"
autoFocus
/>
</Grid>
<Grid item xs={12}>
<input
variant="outlined"
required
fullWidth
name="password"
label="Password"
type="password"
id="password"
onChange={(e) => {
setPassword(e.target.value)
console.log(e.target.value);}}
autoComplete="current-password"
/>
</Grid>
<Grid item xs={12}>
<FormControlLabel
control={<Checkbox value="allowExtraEmails" color="primary" />}
label="I want to receive inspiration, marketing promotions and updates via email."
/>
</Grid>
</Grid>
<Button
type="submit"
fullWidth
variant="contained"
color="primary"
className={classes.submit}
onClick={signup}
>
Sign Up
</Button>
<Grid container justify="flex-end">
<Grid item>
<Link href="#" variant="body2">
Already have an account? Sign in
</Link>
</Grid>
</Grid>
</form>
</div>
<Box mt={5}>
<Copyright />
</Box>
</Container>
);
}
any idea what's happening?

I see two issues here:
You try to access email and password from this.props but you're keeping it as local state variables in your component.
Your signup method is outside of the scope of your functional component, as already mentioned in the comments. You can't access email and password here anyhow.
Move your function into the component function and remove this line const{email,password}=this.props; because email and password will then be available from the outer scope.

Related

React-Realm-Electron import

I'm working on a project using React for GUI, electron and realm.
Everything works fine until I try to Import a "component" from the other .js file
Here is my App.js import section:
import logo from './logo.svg';
import './App.css';
import * as Realm from 'realm';
import Avatar from '#mui/material/Avatar';
import Button from '#mui/material/Button';
import CssBaseline from '#mui/material/CssBaseline';
import TextField from '#mui/material/TextField';
import FormControlLabel from '#mui/material/FormControlLabel';
import Checkbox from '#mui/material/Checkbox';
import Link from '#mui/material/Link';
import Grid from '#mui/material/Grid';
import Box from '#mui/material/Box';
import LockOutlinedIcon from '#mui/icons-material/LockOutlined';
import Typography from '#mui/material/Typography';
import Container from '#mui/material/Container';
import { createTheme, ThemeProvider } from '#mui/material/styles';
import Signin from './Signin';
and my Signin.js file look likes this :
import Avatar from '#mui/material/Avatar';
import Button from '#mui/material/Button';
import CssBaseline from '#mui/material/CssBaseline';
import TextField from '#mui/material/TextField';
import FormControlLabel from '#mui/material/FormControlLabel';
import Checkbox from '#mui/material/Checkbox';
import Link from '#mui/material/Link';
import Grid from '#mui/material/Grid';
import Box from '#mui/material/Box';
import LockOutlinedIcon from '#mui/icons-material/LockOutlined';
import Typography from '#mui/material/Typography';
import Container from '#mui/material/Container';
import { createTheme, ThemeProvider } from '#mui/material/styles';
function Copyright(props) {
return (
<Typography variant="body2" color="text.secondary" align="center" {...props}>
{'Copyright © '}
<Link color="inherit" href="https://mui.com/">
Your Website
</Link>{' '}
{new Date().getFullYear()}
{'.'}
</Typography>
);
}
const theme = createTheme();
export default function SignIn() {
const handleSubmit = (event) => {
event.preventDefault();
const data = new FormData(event.currentTarget);
// eslint-disable-next-line no-console
console.log({
email: data.get('email'),
password: data.get('password'),
});
};
return (
<ThemeProvider theme={theme}>
<Container component="main" maxWidth="xs">
<CssBaseline />
<Box
sx={{
marginTop: 8,
display: 'flex',
flexDirection: 'column',
alignItems: 'center',
}}
>
<Avatar sx={{ m: 1, bgcolor: 'secondary.main' }}>
<LockOutlinedIcon />
</Avatar>
<Typography component="h1" variant="h5">
Sign in
</Typography>
<Box component="form" onSubmit={handleSubmit} noValidate sx={{ mt: 1 }}>
<TextField
margin="normal"
required
fullWidth
id="email"
label="Email Address"
name="email"
autoComplete="email"
autoFocus
/>
<TextField
margin="normal"
required
fullWidth
name="password"
label="Password"
type="password"
id="password"
autoComplete="current-password"
/>
<FormControlLabel
control={<Checkbox value="remember" color="primary" />}
label="Remember me"
/>
<Button
type="submit"
fullWidth
variant="contained"
sx={{ mt: 3, mb: 2 }}
>
Sign In
</Button>
<Grid container>
<Grid item xs>
<Link href="#" variant="body2">
Forgot password?
</Link>
</Grid>
<Grid item>
<Link href="#" variant="body2">
{"Don't have an account? Sign Up"}
</Link>
</Grid>
</Grid>
</Box>
</Box>
<Copyright sx={{ mt: 8, mb: 4 }} />
</Container>
</ThemeProvider>
);
}
here is the error I get in the BrowserWindow console :
Uncaught Error: require() of ES Module C:\Users\valco\Documents\GATO\Main\my_electron_react_application\node_modules\#babel\runtime\helpers\esm\defineProperty.js from C:\Users\valco\Documents\GATO\Main\my_electron_react_application\build\index.html not supported.
Instead change the require of defineProperty.js in C:\Users\valco\Documents\GATO\Main\my_electron_react_application\build\index.html to a dynamic import() which is available in all CommonJS modules.
at __node_internal_captureLargerStackTrace (node:internal/errors:464)
at new NodeError (node:internal/errors:371)
at Object.Module._extensions..js (node:internal/modules/cjs/loader:1144)
at Module.load (node:internal/modules/cjs/loader:988)
at Module._load (node:internal/modules/cjs/loader:829)
at Function.c._load (node:electron/js2c/asar_bundle:5)
at Function.o._load (node:electron/js2c/renderer_init:33)
at Module.require (node:internal/modules/cjs/loader:1012)
at require (node:internal/modules/cjs/helpers:94)
at Object.<anonymous> (defineProperty":1)
at l (index.html:1)
at Module.<anonymous> (main.e3312a17.chunk.js:1)
at l (index.html:1)
at r (index.html:1)
at Array.t [as push] (index.html:1)
at main.e3312a17.chunk.js:1
I know it may have something to do with ES6 and require, or node version, or node-fetch,
Because of realm, I cant just start the script I have to go through a CRADO build before.
When I dont try to import Signin, everything works just fine but as soon as I try to import it... I get this error.
I found the why of the problem :
My app.js is based on React-Native while the Signin.js is React.
It seems like Realm cant work with React..?

Link Button to route to the another component is not working in React js

I am implementing a form and download the text input from the form as a PDF. But i am facing issue while implementing the Next and submit button which can route to my PDF component which are having option to download the form. Can anyone please help me here to resolve this :)
Following is my component named "Map" with Next Button which should Route to the PDF component:
enter code here
import React , { Component} from 'react';
import Button from '#material-ui/core/Button';
import CssBaseline from '#material-ui/core/CssBaseline';
import TextField from '#material-ui/core/TextField';
import FormControlLabel from '#material-ui/core/FormControlLabel';
import Checkbox from '#material-ui/core/Checkbox';
import Link from '#material-ui/core/Link';
import Grid from '#material-ui/core/Grid';
import Typography from '#material-ui/core/Typography';
import { withStyles } from '#material-ui/core/styles';
import Container from '#material-ui/core/Container';
import PDF from './PDF';
const useStyles = (theme) => ({
paper: {
marginTop: "theme.spacing(8)",
display: 'flex',
flexDirection: 'column',
alignItems: 'center',
},
avatar: {
margin: 'spacing(1)',
backgroundColor: 'palette.secondary.main',
alignItems:'center'
},
form: {
width: '100%', // Fix IE 11 issue.
marginTop: 'spacing(3)',
},
submit: {
margin: 'spacing(3, 0, 2)'
},
});
class Map extends React.Component {
userData;
constructor (props) {
super(props);
this.onChangefirstName = this.onChangefirstName.bind(this);
this.onChangelastName = this.onChangelastName.bind(this);
this.onChangeEmail = this.onChangeEmail.bind(this);
this.onChangePhone = this.onChangePhone.bind(this);
this.onSubmit = this.onSubmit.bind(this);
this.state = {
fname: '',
lname:'',
email: '',
phone: '',
postSubmitted:false
}
}
// Form event
onChangefirstName(e) {
this.setState({ fname: e.target.value})
}
onChangelastName(e){
this.setState({lname: e.target.value})
}
onChangeEmail(e){
this.setState({email: e.target.value})
}
onChangePhone(e){
this.setState({phone: e.target.value})
}
onSubmit(e){
e.preventDefault()
}
//React Lifecycle
componentDidMount(){
this.userData = JSON.parse(localStorage.getItem('user'));
if (localStorage.getItem('user')) {
this.setState({
fname: this.userData.fname,
lname: this.userData.lname,
email: this.userData.email,
phone: this.userData.phone
})
} else {
this.setState({
fname: '',
lname: '',
email: '',
phone: ''
})
}
}
componentWillUpdate(nextProps, nextState){
localStorage.setItem('user', JSON.stringify(nextState));
}
//Validation
submitPost = e => {
if (!this.state.fname || !this.state.lname || !this.state.email) {
alert(" All fields are required")
e.preventDefault();
} else {
this.setState({
postSubmitted: true
});
}
}
render(){
const {classes} = this.props;
return (
<>
{
<Container component="main" maxWidth="xs">
<CssBaseline />
<div className={classes.paper}><br></br>
<Typography component="h1" variant="h5">
Tell About Yourself
</Typography> <br></br>
<form className={classes.form} onSubmit={this.onSubmit}>
<Grid container spacing={2}>
<Grid item xs={12} sm={6}>
<TextField
autoComplete="fname"
name="firstName"
variant="outlined"
required
fullWidth
id="firstName"
label="First Name"
autoFocus
value={this.state.fname}
onChange={this.onChangefirstName}
/>
</Grid>
<Grid item xs={12} sm={6}>
<TextField
variant="outlined"
required
fullWidth
id="lastName"
label="Last Name"
name="lastName"
autoComplete="lname"
value={this.state.lname}
onChange={this.onChangelastName}
/>
</Grid>
<Grid item xs={12}>
<TextField
variant="outlined"
required
fullWidth
id="email"
label="Email Address"
name="email"
value={this.state.email}
onChange={this.onChangeEmail}
/>
</Grid>
<Grid item xs={12}>
<TextField
variant="outlined"
required
fullWidth
name="phone"
label="Phone Number"
type="phone"
id="phone"
autoComplete="phone"
value={this.state.phone}
onChange={this.onChangePhone}
/>
</Grid>
<Grid item xs={12}>
<FormControlLabel
control={<Checkbox value="allowExtraEmails" color="primary" /> }
label="Your contact details will be shared with TØyen Unlimited"
alignItems='row'
/>
</Grid>
</Grid><br></br>
<Button
fullWidth
variant="contained"
color="secondary"
className={classes.submit}
component={Link}
to="/PDF"
>
Submit and Go to next
</Button>
</form>
</div>
</Container>
}
</>
);
}
}
export default withStyles(useStyles, {withTheme:true}) (Map)
Following is my App.js component where i have defined Route property:
import './App.css';
import { makeStyles} from '#material-ui/core/styles'
import { BrowserRouter as Router, Route } from "react-router-dom";
import NavBar from './Components/NavBar';
import Home from './Components/Home';
import About from './Components/About';
import Map from './Components/Map';
import Footer from './Components/Footer';
import PDF from './Components/PDF';
const styles = makeStyles({
wrapper: {
width: "65%",
margin: "auto" ,
textAlign: "center",
},
bigSpace: {
marginTop: "5rem"
},
littleSpace: {
marginTop: "2.5rem"
},
title: {
color: "#314976",
font: "Italic"
}
})
function App() {
const classes = styles();
return (
<Router>
<div className="App">
<NavBar/>
<div className={classes.wrapper}>
<switch>
<Route exact path="/">
<Home/>
</Route>
<Route exact path="/About">
<About/>
</Route>
<Route exact path="/Map">
<Map/>
</Route>
<Route exact path="/PDF" >
<PDF/>
</Route>
</switch>
</div>
<div className={classes.bigSpace}>
<Footer/>
</div>
</div>
</Router>
);
}
export default App;
I think the issue here is that you're importing and using the Link component from Material-UI and not the Link component from react-router-dom.
import Link from '#material-ui/core/Link';
Material-UI Link
From what I can tell from the Material-UI Link component renders a normal anchor tag, i.e. to link out to external resources, not to routes within the app. In other words, the link isn't using the routing context to handle any navigation.
I believe the simplest resolution is to just import the react-router-dom Link component instead.
import { Link } from 'react-router-dom';
...
<Button
fullWidth
variant="contained"
color="secondary"
className={classes.submit}
component={Link}
to="/PDF"
>
Submit and Go to next
</Button>

Link tag changes my history location but then changes back to original home page React.js

So I have been having this issue with a project I've been working on for 2 days now and I don't know why. I have used React-router-dom before for my webapps and I have never encountered this issue in all the months I've used React.js I basically have my Switch component, BrowserRouter wrapped around App.js, and everything, but every time I click the link to my new route "/register", the URL would change for a few 2 seconds and then change back to my login homepage. this happens without me doing anything or clicking anything. I've tried changing link tag attribute from to="/register" to href="/register" but that didn't work. It's infuriating, Here's my code:
Index.js
import ReactDOM from 'react-dom';
import './index.css';
import App from './App';
import {BrowserRouter} from 'react-router-dom';
ReactDOM.render(
<BrowserRouter>
<App />
</BrowserRouter>,
document.getElementById('root')
);
App.js
import React,{Component} from 'react';
import { Router, Switch, Route, withRouter, Link} from 'react-router-dom'
import HomePage from "./components/HomePage";
import Register from "./components/Register"
import Dashboard from "./components/Dashboard"
// import Link from '#material-ui/core/Link';
// import { background } from "./images/7f76e8e7692375107e5998013155af0d.jpg";
// import { TravelerEffect, MosaicGroundEffect, OceanEffect,
// RainEffect, SeaWaveEffect, SnowFallEffect, SnowFallSlowEffect,
// SpacingEffect, CloudWaveEffect
// } from 'react-background-animation'
class App extends Component {
state = {
user: {
email: "",
username: "",
is_active: "",
first_name: "",
last_name: "",
bio: "",
age: "",
birth_place: "",
school: "",
occupation: "",
what_are_you_seeking_on_site: "",
profile_pic: null,
loginErrors: "",
},
token: "",
}
handleResponse (resp) {
console.log(resp.user);
if (resp.user) {
localStorage.setItem('token', resp.token)
this.setState({
user: resp.user,
token: resp.token
}, () => {
this.props.history.push("/dashboard")
})
}
else {
alert(resp.error)
}
}
componentDidMount(){
if (localStorage.getItem("token")) {
fetch('http://localhost:8000/current_user/', {
headers: {
Authorization: `Bearer ${localStorage.token}`
}
})
.then(r => r.json())
.then(this.handleResp)
}
}
handleRegister(newUser){
fetch( "http://127.0.0.1:8000/rest-auth/registration/", {
method: "POST",
headers: {
'content-type': "application/json"
},
body: JSON.stringify(newUser)
})
.then(res => res.json())
.then(this.handleResponse)
}
handleLogin(returningUser){
fetch('http://127.0.0.1:8000/rest-auth/login/', {
method: 'POST',
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify(returningUser)
})
.then(res => res.json())
.then(this.handleResponse)
}
renderRegisterForm = (routerProps) => {
if (routerProps.location.pathname === "/register") {
// debugger
return <Register formName="Register Form"
handleSubmit={this.handleRegister}
/>
}else if(routerProps.location.pathname === "/") {
return <HomePage formName="Log into Account"
handleSubmit={this.handleLogin}
/>
}
}
render() {
return (
<div>
{/* <Link to="/register">Sign Up</Link> */}
<Switch>
<Route exact path="/" render={this.renderRegisterForm} />
<Route exact path="/register" render={this.renderRegisterForm} />
<Route path="/dashboard" exact component={Dashboard} />
<Route render={ () => <p>Page not Found</p> } />
</Switch>
{/* <Link href="/register"
// onClick={this.handleRegisterLinkPage}
variant="body1">
{"Don't have an account? Sign Up"}
</Link> */}
</div>
);
}
}
export default withRouter(App);
my HomePage.jsx (which is basically my login page)
import React from 'react';
import {Redirect} from "react-router-dom"
import Avatar from '#material-ui/core/Avatar';
import Button from '#material-ui/core/Button';
import CssBaseline from '#material-ui/core/CssBaseline';
import TextField from '#material-ui/core/TextField';
import FormControlLabel from '#material-ui/core/FormControlLabel';
import Checkbox from '#material-ui/core/Checkbox';
import Link from '#material-ui/core/Link';
import Paper from '#material-ui/core/Paper';
import Box from '#material-ui/core/Box';
import Grid from '#material-ui/core/Grid';
// import LockOutlinedIcon from '#material-ui/icons/LockOutlined';
import Typography from '#material-ui/core/Typography';
import { withStyles } from '#material-ui/core/styles';
const useStyles = theme => ({
root: {
height: '100vh',
},
image: {
backgroundImage: 'url(https://source.unsplash.com/random)',
backgroundRepeat: 'no-repeat',
backgroundColor:
theme.palette.type === 'light' ? theme.palette.grey[50] : theme.palette.grey[900],
backgroundSize: 'cover',
backgroundPosition: 'center',
},
paper: {
margin: theme.spacing(8, 4),
display: 'flex',
flexDirection: 'column',
alignItems: 'center',
},
avatar: {
margin: theme.spacing(1),
backgroundColor: theme.palette.secondary.main,
},
form: {
width: '100%', // Fix IE 11 issue.
marginTop: theme.spacing(1),
},
submit: {
margin: theme.spacing(3, 0, 2),
},
});
function Copyright() {
return (
<Typography variant="body2" color="textSecondary" align="center">
{'Copyright © '}
<Link color="inherit" href="https://material-ui.com/">
Your Website
</Link>{' '}
{new Date().getFullYear()}
{'.'}
</Typography>
);
}
class HomePage extends React.Component {
// handleRegisterLinkPage = (event) => {
// event.preventDefault()
// return<Redirect to={"/register"}/>
// // debugger
// }
render(){
const {classes} = this.props
return (
<Grid container component="main" className={classes.root}>
<CssBaseline />
<Grid item xs={false} sm={4} md={7} className={classes.image} />
<Grid item xs={12} sm={8} md={5} component={Paper} elevation={6} square>
<div className={classes.paper}>
<Avatar className={classes.avatar}>
{/* <LockOutlinedIcon /> */}
</Avatar>
<Typography component="h1" variant="h5">
Sign in
</Typography>
<form className={classes.form} noValidate>
<TextField
variant="outlined"
margin="normal"
required
fullWidth
id="email"
label="Email Address"
name="email"
autoComplete="email"
autoFocus
/>
<TextField
variant="outlined"
margin="normal"
required
fullWidth
name="password"
label="Password"
type="password"
id="password"
autoComplete="current-password"
/>
<FormControlLabel
control={<Checkbox value="remember" color="primary" />}
label="Remember me"
/>
<Button
type="submit"
fullWidth
variant="contained"
color="primary"
className={classes.submit}
>
Sign In
</Button>
<Grid container>
<Grid item xs>
{/* <Link href="#" variant="body2">
Forgot password?
</Link> */}
</Grid>
<Grid item>
<Link href="/register"
// onClick={this.handleRegisterLinkPage}
variant="body1">
<Button> Don't have an account? Sign Up</Button>
</Link>{' '}
</Grid>
</Grid>
<Box mt={5}>
<Copyright />
</Box>
</form>
</div>
</Grid>
</Grid>
);
}
}
export default withStyles(useStyles)(HomePage)
And Lastly My register page, which I feel I shouldn't have to show, but here it is anyway
import React, { useState, useEffect } from 'react';
import Avatar from '#material-ui/core/Avatar';
import Button from '#material-ui/core/Button';
import CssBaseline from '#material-ui/core/CssBaseline';
import TextField from '#material-ui/core/TextField';
import FormControlLabel from '#material-ui/core/FormControlLabel';
import Checkbox from '#material-ui/core/Checkbox';
import Link from '#material-ui/core/Link';
import Grid from '#material-ui/core/Grid';
import Box from '#material-ui/core/Box';
import LockOutlinedIcon from '#material-ui/icons/LockOutlined';
import Typography from '#material-ui/core/Typography';
import { makeStyles } from '#material-ui/core/styles';
import Container from '#material-ui/core/Container';
import TextareaAutosize from '#material-ui/core/TextareaAutosize';
import { MuiPickersUtilsProvider, KeyboardDatePicker } from '#material-ui/pickers';
import FormControl from '#material-ui/core/FormControl';
import FormLabel from '#material-ui/core/FormLabel';
import Radio from '#material-ui/core/Radio';
import RadioGroup from '#material-ui/core/RadioGroup';
import DateFnsUtils from '#date-io/date-fns';
function Copyright() {
return (
<Typography variant="body2" color="textSecondary" align="center">
{'Copyright © '}
<Link color="inherit" href="https://material-ui.com/">
Your Website
</Link>{' '}
{new Date().getFullYear()}
{'.'}
</Typography>
);
}
const useStyles = makeStyles((theme) => ({
paper: {
marginTop: theme.spacing(8),
display: 'flex',
flexDirection: 'column',
alignItems: 'center',
},
avatar: {
margin: theme.spacing(1),
backgroundColor: theme.palette.secondary.main,
},
form: {
width: '100%', // Fix IE 11 issue.
marginTop: theme.spacing(3),
},
submit: {
margin: theme.spacing(3, 0, 2),
},
}));
export default function Register() {
const classes = useStyles();
const [email, setEmail] = useState(" ")
const [password, setPassword] = useState(" ")
const [confirmPassword, setConfirmPassword] = useState(" ")
const [username, setUsername] = useState(" ")
const [birthPlace, setBirthPlace] = useState(" ")
const [bio, setBio] = useState(" ")
const [school, setSchool] = useState(" ")
const [firstName, setFirstName] = useState(" ")
const [lastName, setLastName] = useState(" ")
const [occupation, setOccupation] = useState(" ")
const [what_are_you_seeking_on_site, setWhat_are_you_seeking_on_site] = useState("Friendship")
const [age, setAge] = useState(new Date('2014-08-18T21:11:54'));
const [errors, setErrors] = useState(" ")
// const [selectedDate, setSelectedDate] =
// const [value, setValue] = React.useState('Friendship');
useEffect(() => {
if (localStorage.getItem('token') !== null) {
window.location.replace('http://localhost:3000/dashboard');
} else {
window.location.replace('http://localhost:3000/')
}
}, []);
const handleSubmit = e => {
e.preventDefault();
const user = {
email: email,
username: username,
birthPlace: birthPlace,
bio: bio,
school: school,
age: age,
password: password,
confirmPassword: confirmPassword,
firstName: firstName,
lastName: lastName,
occupation: occupation,
what_are_you_seeking_on_site: what_are_you_seeking_on_site,
};
fetch('http://127.0.0.1:8000/rest-auth/registration/', {
method: 'POST',
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify(user)
})
.then(res => res.json())
.then(data => {
if (data.key) {
localStorage.clear();
localStorage.setItem('token', data.key);
window.location.replace('http://localhost:3000/dashboard');
} else {
setEmail('');
setPassword('');
setConfirmPassword('');
localStorage.clear();
setErrors(true);
}
});
};
const handleChange = (event) => {
setWhat_are_you_seeking_on_site(event.target.value);
};
const handleDateChange = (date) => {
setAge(date);
};
return (
<Container component="main" maxWidth="xs">
<CssBaseline />
<div className={classes.paper}>
<Avatar className={classes.avatar}>
<LockOutlinedIcon />
</Avatar>
<Typography component="h1" variant="h5">
Sign up
</Typography>
<form className={classes.form} onSubmit={handleSubmit} noValidate>
<Grid container spacing={2}>
<Grid item xs={12} sm={6}>
<Grid item xs={12} sm={6}>
<TextField
autoComplete="username"
name="Username"
variant="outlined"
required
fullWidth
id="Username"
label="Username"
autoFocus
value={e => setUsername(e.target.value)}
/>
</Grid>
<TextField
autoComplete="fname"
name="firstName"
variant="outlined"
required
fullWidth
id="firstName"
label="First Name"
autoFocus
value={e => setFirstName(e.target.value)}
/>
</Grid>
<Grid item xs={12} sm={6}>
<TextField
variant="outlined"
required
fullWidth
id="lastName"
label="Last Name"
name="lastName"
value={e => setLastName(e.target.value)}
/>
</Grid>
<Grid item xs={12}>
<TextField
variant="outlined"
required
fullWidth
id="email"
label="Email Address"
name="email"
value={e => setEmail(e.target.value)}
/>
</Grid>
<Grid item xs={12}>
<TextField
variant="outlined"
required
fullWidth
name="password"
label="Password"
type="password"
id="password"
value={e => setPassword(e.target.value)}
/>
</Grid>
<Grid item xs={12}>
<TextField
variant="outlined"
required
fullWidth
name="Confirm password"
label="Confirm Password"
type="password2"
id="password2"
value={e => setConfirmPassword(e.target.value)}
/>
</Grid>
<Grid item xs={12}>
<TextareaAutosize
aria-label="minimum height"
fullWidth
label="Bio"
rowsMin={3}
placeholder="Minimum 3 rows"
value={e => setBio(e.target.value)}
/>
</Grid>
<Grid item xs={12}>
<TextField
variant="outlined"
required
fullWidth
name="Birth Place"
label="Where were you born"
id="birthPlace"
value={e => setBirthPlace(e.target.value)}
/>
</Grid>
<Grid item xs={12}>
<TextField
variant="outlined"
required
fullWidth
name="School"
label="School"
id="School"
value={e => setSchool(e.target.value)}
/>
</Grid>
<Grid item xs={12}>
<TextField
variant="outlined"
required
fullWidth
name="Occupation"
label="Occupation"
id="Occupation"
value={e => setOccupation(e.target.value)}
/>
</Grid>
<Grid item xs={12}>
<FormControl component="fieldset">
<FormLabel component="legend">What are you here for</FormLabel>
<RadioGroup aria-label="what_are_you_seeking_on_site" name="what_are_you_seeking_on_site" value={what_are_you_seeking_on_site} onChange={handleChange}>
<FormControlLabel value="Dating" control={<Radio />} label="Dating" />
<FormControlLabel value="Friendship" control={<Radio />} label="Friendship" />
<FormControlLabel value="Networking" control={<Radio />} label="Networking" />
<FormControlLabel value="Business" control={<Radio />} label="Business" />
</RadioGroup>
</FormControl>
</Grid>
<Grid item xs={12}>
<MuiPickersUtilsProvider utils={DateFnsUtils}>
<KeyboardDatePicker
margin="normal"
id="date-picker-dialog"
label="Date picker dialog"
format="MM/dd/yyyy"
// value={selectedDate}
onChange={handleDateChange}
KeyboardButtonProps={{
'aria-label': 'change date',
}}
value={e => setAge(e.target.value)}
/>
</MuiPickersUtilsProvider>
</Grid>
<Grid item xs={12}>
<FormControlLabel
control={<Checkbox value="allowExtraEmails" color="primary" />}
label="I want to receive inspiration, marketing promotions and updates via email."
/>
</Grid>
</Grid>
<Button
type="submit"
fullWidth
variant="contained"
color="primary"
className={classes.submit}
>
Sign Up
</Button>
<Grid container justify="flex-end">
<Grid item>
<Link href="/" variant="body2">
Already have an account? Sign in
</Link>
</Grid>
</Grid>
</form>
</div>
<Box mt={5}>
<Copyright />
</Box>
</Container>
);
}
Please Help me
When your Register component mounts you've an useEffect hook that runs and either bounces the user to "/dashboard" or "/".
useEffect(() => {
if (localStorage.getItem('token') !== null) {
window.location.replace('http://localhost:3000/dashboard');
} else {
window.location.replace('http://localhost:3000/')
}
}, []);
If the token exists and isn't null then bouncing a user to the dashboard path is probably acceptable. You may not want to bounce users to the homepage when they are trying to register so you can likely remove the else branch entirely.
useEffect(() => {
if (localStorage.getItem('token') !== null) {
window.location.replace('http://localhost:3000/dashboard');
}
}, []);

React / MUI : How to call other class with hook to button in main App.js

I'm new to React/MUI.. I'm creating different components for now for a website, so the UI for now doesn't matter.
I'm facing this problem while trying to do a button to link me to the Sign Up page (Doing the same for Sign In):
Error: Invalid hook call. Hooks can only be called inside of the body of a function component. This could happen for one of the following reasons: ...
The following is my code:
SignUp.js
import React from 'react';
import Avatar from '#material-ui/core/Avatar';
import Button from '#material-ui/core/Button';
import CssBaseline from '#material-ui/core/CssBaseline';
import TextField from '#material-ui/core/TextField';
import FormControlLabel from '#material-ui/core/FormControlLabel';
import Checkbox from '#material-ui/core/Checkbox';
import Link from '#material-ui/core/Link';
import Grid from '#material-ui/core/Grid';
import Box from '#material-ui/core/Box';
import LockOutlinedIcon from '#material-ui/icons/LockOutlined';
import Typography from '#material-ui/core/Typography';
import { makeStyles } from '#material-ui/core/styles';
import Container from '#material-ui/core/Container';
const useStyles = makeStyles((theme) => ({
paper: {
marginTop: theme.spacing(8),
display: 'flex',
flexDirection: 'column',
alignItems: 'center',
},
avatar: {
margin: theme.spacing(1),
backgroundColor: theme.palette.secondary.main,
},
form: {
width: '100%', // Fix IE 11 issue.
marginTop: theme.spacing(3),
},
submit: {
margin: theme.spacing(3, 0, 2),
},
}));
export default function SignUp() {
const classes = useStyles();
return (
<Container component="main" maxWidth="xs">
<CssBaseline />
<div className={classes.paper}>
<Avatar className={classes.avatar}>
<LockOutlinedIcon />
</Avatar>
<Typography component="h1" variant="h5">
Sign up
</Typography>
<form className={classes.form} noValidate>
<Grid container spacing={2}>
<Grid item xs={12} sm={6}>
<TextField
autoComplete="fname"
name="firstName"
variant="outlined"
required
fullWidth
id="firstName"
label="First Name"
autoFocus
/>
</Grid>
<Grid item xs={12} sm={6}>
<TextField
variant="outlined"
required
fullWidth
id="lastName"
label="Last Name"
name="lastName"
autoComplete="lname"
/>
</Grid>
<Grid item xs={12}>
<TextField
variant="outlined"
required
fullWidth
id="email"
label="Email Address"
name="email"
autoComplete="email"
/>
</Grid>
<Grid item xs={12}>
<TextField
variant="outlined"
required
fullWidth
name="password"
label="Password"
type="password"
id="password"
autoComplete="current-password"
/>
</Grid>
<Grid item xs={12}>
<FormControlLabel
control={<Checkbox value="allowExtraEmails" color="primary" />}
label="I want to receive inspiration, marketing promotions and updates via email."
/>
</Grid>
</Grid>
<Button
type="submit"
fullWidth
variant="contained"
color="primary"
className={classes.submit}
>
Sign Up
</Button>
<Grid container justify="flex-end">
<Grid item>
<Link href="#" variant="body2">
Already have an account? Sign in
</Link>
</Grid>
</Grid>
</form>
</div>
<Box mt={5}>
<Copyright />
</Box>
</Container>
);
}
App.js
import React from 'react';
import Container from '#material-ui/core/Container';
import Typography from '#material-ui/core/Typography';
import SignUp from './sign-up/SignUp.js';
import SignIn from './sign-in/SignIn.js';
import Box from '#material-ui/core/Box';
import Link from '#material-ui/core/Link';
import { Button, Paper } from '#material-ui/core';
export default function App() {
return (
<div>
<Container maxWidth="sm">
<Box my={4}>
<Typography variant="h4" component="h1" gutterBottom>
Creating a website!
</Typography>
<ProTip />
<button onClick={SignUp}>
Click me!
</button>
<SignIn />
<Copyright />
</Box>
</Container>
</div>
);
}
How do I properly convert in this case?
You're trying to call a React component as an event handler:
<button onClick={SignUp}>
That will not work. Instead you can for example create a flag, set it to true in the onClick handler and then render SignUp based on this flag.
const [showSignUp, setShowSignUp]= React.useState(false)
...
<button onClick={()=>setShowSignUp(s=>!s)}>Click me!</button>
{showSignUp ? <SignUp /> : <SignIn />}

How do I get the likes length to update in real time after clicking clicking like

If I click to remove the first like on the first goal, I can see the Redux action firing (using Redux DevTools) for the like being updated. But the number beside is not updating. When I check the console it doesn't appear that anything is refreshing. When I refresh the page, it shows the updated number that was previously liked (the 0 becomes a 1), but I have to refresh the page to see this update. How can I get the number to update in real time without having to refresh the page?
import React, { useEffect } from "react";
import Moment from "react-moment";
import PropTypes from "prop-types";
import { Link } from "react-router-dom";
import { connect } from "react-redux";
import { addLike, removeLike } from "../../actions/goal";
import { getGoals } from "../../actions/goal";
import Spinner from "../layout/Spinner";
import Navbar from "../dashboard/Navbar";
import ThumbUpAltIcon from "#material-ui/icons/ThumbUpAlt";
import ThumbDownAltIcon from "#material-ui/icons/ThumbDownAlt";
import ChatIcon from "#material-ui/icons/Chat";
import DeleteIcon from "#material-ui/icons/Delete";
import DoneIcon from "#material-ui/icons/Done";
import {
Typography,
Container,
CssBaseline,
makeStyles,
Grid,
Avatar,
Paper,
Button
} from "#material-ui/core";
const useStyles = makeStyles(theme => ({
paper: {
height: "auto",
marginBottom: theme.spacing(3)
},
actionButtons: {
marginTop: "3vh"
},
profileHeader: {
textAlign: "center",
marginBottom: 20
},
avatar: {
width: theme.spacing(7),
height: theme.spacing(7)
}
}));
const Goals = ({
getGoals,
auth,
addLike,
removeLike,
goal: { goals, user, loading }
}) => {
useEffect(() => {
getGoals();
}, [getGoals]);
const classes = useStyles();
return loading ? (
<>
<Navbar />
<Container component="main" maxWidth="xs">
<CssBaseline />
<div className={classes.paper}>
<Spinner />
</div>
</Container>
</>
) : (
<>
<CssBaseline />
<Navbar />
<main>
<Container>
<Typography variant="h2" className={classes.profileHeader}>
Goals
</Typography>
{/* parent grid */}
<Grid container spacing={4}>
{goals.map(singleGoal => (
<Grid
className={classes.paper}
key={singleGoal._id}
spacing={1}
container
item
direction="row"
alignItems="center"
component={Paper}
>
<Grid
item
container
direction="column"
justify="center"
alignItems="center"
xs={3}
>
<Avatar className={classes.avatar} src={singleGoal.avatar} />
<Typography variant="caption">
{singleGoal.first_name} {singleGoal.last_name}
</Typography>
<Typography variant="caption" className={classes.postedOn}>
Posted on{" "}
<Moment format="MM/DD/YYYY">{singleGoal.date}</Moment>
</Typography>
</Grid>
<Grid container item direction="column" xs={9}>
<Typography variant="body1">{singleGoal.text}</Typography>
<Grid item className={classes.actionButtons}>
<Button size="small" onClick={e => addLike(singleGoal._id)}>
<ThumbUpAltIcon />
</Button>
<Typography variant="caption">
{singleGoal.likes.length}
</Typography>
<Button
size="small"
onClick={e => removeLike(singleGoal._id)}
>
<ThumbDownAltIcon />
</Button>
<Button href={`/goal/${singleGoal._id}`} size="small">
<ChatIcon />
</Button>
{!auth.loading && singleGoal.user === auth.user._id && (
<Button size="small">
<DoneIcon />
</Button>
)}
{!auth.loading && singleGoal.user === auth.user._id && (
<Button size="small">
<DeleteIcon />
</Button>
)}
</Grid>
</Grid>
</Grid>
))}
</Grid>
</Container>
</main>
</>
);
};
Goals.propTypes = {
getGoals: PropTypes.func.isRequired,
goal: PropTypes.object.isRequired
};
const mapStateToProps = state => ({
goal: state.goal,
auth: state.auth
});
export default connect(mapStateToProps, { getGoals, addLike, removeLike })(
Goals
);
I will need to see the rest of your code to be sure, but it seems you are dispatching your action but you are not updating your store, it could be a mistake in your reducer.

Categories

Resources