Hey I have tried a lot of things but I can't seem to get this thing to work I am trying to make a simple modal using material UI but whenever I try to change state it's showing me a blank white page. does anyone have any idea why is it happening here's my code
a
import {Button,Modal} from "#material-ui/core";
import {useState} from "react";
import RegisterBody from '../Register/RegisterForm'
import LoginBody from '../Login/LoginForm'
const UserModel = () => {
const [isOpen, setIsOpen] = useState(false)
const [isLoginModel, setLoginModel] = useState();
const [MainModelBody] = useState(LoginBody);
function handleRegister() {
if (!isLoginModel) {
console.log("Register")
//Todo: Send Register Request
} else {
MainModelBody.setState(RegisterBody)
setLoginModel(false)
}
}
function handleSignIn() {
if (isLoginModel) {
console.log("Login")
//Todo: send Sign in request
} else {
MainModelBody.setState(LoginBody)
setLoginModel(true)
}
}
function handleUserModel() {
setIsOpen(!isOpen)
}
return (
<>
<Button className="userActionButton" onClick={handleUserModel}>Sign In</Button>
<Modal open={isOpen}
onClose={!isOpen}
disablePortal
disableEnforceFocus
disableAutoFocus
aria-labelledby="simple-modal-title"
aria-describedby="simple-modal-description"
>
<div className = 'UserModel'>
<LoginBody/>
<Button onClick={handleRegister}>Register</Button>
<Button onClick={handleSignIn}>Sign In</Button>
</div>
</Modal>
</>
);
}
export default UserModel
LoginBody
import {useState} from 'react';
import LoginElements from './LoginElements';
import {FormControl} from "#material-ui/core";
const LoginForm = ()=> {
const [email, setEmail] = useState('')
const [password, setPassword] = useState('')
const handleSubmit = (e) => {
e.preventDefault();
const user = {email, password}
console.log(user)
};
return (
<div className="form">
<FormControl noValidate autoComplete="off" onSubmit={handleSubmit}>
<LoginElements
email={email}
password={password}
setEmail={setEmail}
setPassword={setPassword}
/>
</FormControl>
</div>
);
}
export default LoginForm;
LoginElements
import {Button, TextField} from "#material-ui/core";
const LoginElements = (props) => {
return (
<>
<TextField label="Email" type="email" required value={props.email} onChange={(e) => props.setEmail(e.target.value)}/>
<br/>
<TextField label="Password" type="password" required value={props.password} onChange={(e) => props.setPassword(e.target.value)}/>
<br/>
<Button variant="contained" type="submit">Login</Button>
<Button variant="contained" type="register">Register</Button>
<br/>
<label>{props.email}</label>
<label>{props.password}</label>
</>
)
}
export default LoginElements;
RegisterBody
import {useState} from 'react';
import RegisterElements from './RegisterElements';
const LoginForm = ()=> {
const [email, setEmail] = useState('')
const [confirmEmail, setConfirmEmail] = useState('')
const [password, setPassword] = useState('')
const [confirmPassword, setConfirmPassword] = useState('')
const handleSubmit = (e) => {
e.preventDefault();
const user = {email, password}
console.log(user)
};
return (
<div className="form">
<form noValidate autoComplete="off" onSubmit={handleSubmit}>
<RegisterElements
email={email}
confirmEmail={email}
password={password}
confirmPassword={password}
setEmail={setEmail}
setConfirmEmail={setEmail}
setPassword={setPassword}
setConfirmPassword={setPassword}
/>
</form>
</div>
);
}
export default LoginForm;
Register Elements
import {Button, TextField} from "#material-ui/core";
const RegisterElements = (props) => {
return (
<>
<TextField label="Confirm Email" type="email" required value={props.email}
onChange={(e) => props.setEmail(e.target.value)}/>
<TextField label="Confirm Email" type="email" required value={props.confirmEmail}
onChange={(e) => props.setConfirmEmail(e.target.value)}/>
<br/>
<TextField label="Password"
type="password"
required value={props.password}
onChange={(e) => props.setPassword(e.target.value)}/>
<TextField label="Confirm Password" required value={props.confirmPassword}
onChange={(e) => props.setConfirmPassword(e.target.value)}/>
<br/>
<Button variant="contained" type="Login">Login</Button>
<Button variant="contained" type="submit">Login</Button>
<label>{props.email}</label>
<label>{props.password}</label>
</>
)
}
export default RegisterElements;
My apologies for bad code i am new with react
You are "toggling" the isLoginModel state but you only render LoginBody in the JSX.
You should be able to use the isLoginModel state and conditionally render either the LoginBody or RegisterBody component into the modal body. There's really no need for the extra state to hold a component reference.
import {Button,Modal} from "#material-ui/core";
import {useState} from "react";
import RegisterBody from '../Register/RegisterForm'
import LoginBody from '../Login/LoginForm'
const UserModel = () => {
const [isOpen, setIsOpen] = useState(false)
const [isLoginModel, setLoginModel] = useState(true); // login by default
function handleRegister() {
if (!isLoginModel) {
console.log("Register");
// TODO: Send Register Request
} else {
setLoginModel(false);
}
}
function handleSignIn() {
if (isLoginModel) {
console.log("Login");
// TODO: send Sign in request
} else {
setLoginModel(true);
}
}
function handleUserModel() {
setIsOpen(isOpen => !isOpen);
}
return (
<>
<Button className="userActionButton" onClick={handleUserModel}>Sign In</Button>
<Modal open={isOpen}
onClose={!isOpen}
disablePortal
disableEnforceFocus
disableAutoFocus
aria-labelledby="simple-modal-title"
aria-describedby="simple-modal-description"
>
<div className='UserModel'>
{isLoginModel ? <LoginBody /> : <RegisterBody />} // <-- condition render
<Button onClick={handleRegister}>Register</Button>
<Button onClick={handleSignIn}>Sign In</Button>
</div>
</Modal>
</>
);
}
Related
I am now following this youtube video to develop an Instagram clone app by using React with firebase.
The error occurred at the point below, on the video at 2:36:29.
It says "Syntax error: Unexpected token (93:12)"
{user?.displayName ? (
<ImageUpload username={user.displayName} />
) : (
<h3>sorry you need to login to upload</h3>
)}
what I tried
・Just put <ImageUpload username={user.displayName} />
=> I got 「firebase is not defined」 error on the other js file.
・put "user.displayName" instead of "user?.displayName" (? is erased)
=> more complicated error occur that "TypeError: Cannot read properties of null (reading 'displayName')"
・Put {user ? (<ImageUpload username={user.displayName} />) : (<h3>Sorry you need to login !!</h3>)} eraced displayName
=> only visual works(surely, the username is not given in this case)
Adobe three tries, I guess displayName is the main point to solve the issue...
If you are good at React.js or you have seen the same error, please give me advice.
Whole App.js codes↓
App.js
import React, { useState, useEffect } from 'react'
import './App.css';
import Post from './Post';
import { db, auth } from './firebase';
import Modal from '#mui/material/Modal';
import Box from '#mui/material/Box';
import Button from '#mui/material/Button';
import Input from '#mui/material/Input';
//import Typography from '#mui/material/Typography';
import ImageUpload from './ImageUpload';
const style = {
position: 'absolute',
top: '50%',
left: '50%',
transform: 'translate(-50%, -50%)',
width: 400,
bgcolor: 'background.paper',
border: '2px solid #000',
boxShadow: 24,
p: 4,
};
function App() {
const [posts, setPosts] = useState([]);
const [open, setOpen] = React.useState(false);
const [openSignIn, setOpenSignIn] = useState(false);
const handleOpen = () => setOpen(true);
const handleClose = () => setOpen(false);
const [username, setUsername] = useState('');
const [email, setEmail] = useState('');
const [password, setPassword] = useState('');
const [user, setUser] = useState(null);
useEffect(() => {
const unsubscribe = auth.onAuthStateChanged((authUser) => {
if (authUser) {
//User has logged IN
console.log(authUser);
setUser(authUser);
//↑ is keep user logged in after refresh
} else {
//User has logged OUT
setUser(null);
}
})
return () => {
//perform some cleanup actions
unsubscribe(null);
}
}, [user, username]);
//useEffect => where the code runs, last []) means the code runs only once
useEffect(() => {
db.collection('posts').onSnapshot(snapshot => {
setPosts(snapshot.docs.map(doc => ({
id: doc.id,
post: doc.data()
})));
})
}, []);
//signup func
const signup = (event) => {
event.preventDefault();
auth
.createUserWithEmailAndPassword(email, password)
.then((authUser) => {
return authUser.user.updateProfile({
displayName: username
})
})
.catch((error) => alert(error.message));
setOpen(false);
}
//signin func
const signin = (event) => {
event.preventDefault();
auth
.signInWithEmailAndPassword(email, password)
.catch((error) => alert(error.message));
setOpenSignIn(false);
}
return (
<div className="app">
{user.displayName ? (
<ImageUpload username={user.displayName} />
) : (
<h3>sorry you need to login to upload</h3>
)}
<div className="app__header">
<img
className="app__headerImage"
src="https://www.instagram.com/static/images/web/mobile_nav_type_logo.png/735145cfe0a4.png"
alt="HeaderImage"
/>
{user ? (
<Button onClick={() => auth.signOut()}>Logout</Button>
) : (
<div className="app__loginContainer">
<Button onClick={() => setOpenSignIn(true)}>SignIn</Button>
<Button onClick={() => setOpen(true)}>SignUp</Button>
</div>
)}
</div>
<Modal
open={open}
onClose={() => setOpen(false)}
>
<Box sx={style}>
<form className="app__signup">
<center>
<img
className="app__headerImage"
src="https://www.instagram.com/static/images/web/mobile_nav_type_logo.png/735145cfe0a4.png"
alt="HeaderImage"
/>
</center>
<Input
type="text"
placeholder="username"
//at first, ↓ was value={username}, but typing cannot be shown on the screen in that case,
//https://stackoverflow.com/questions/34006333/cant-type-in-react-input-text-field
//↑is the trouble shooting, which says try defaultValue instead of value(V is capital).
defaultValue={username}
onChange={(e) => setUsername(e.target.value)}
/>
<Input
type="text"
placeholder="email"
defaultValue={email}
onChange={(e) => setEmail(e.target.value)}
/>
<Input
type="text"
placeholder="password"
defaultValue={password}
onChange={(e) => setPassword(e.target.value)}
/>
<center>
<Button type="submit" onClick={signup}>SignUp</Button>
</center>
</form>
</Box>
</Modal>
<Modal
//signupModal
open={openSignIn}
onClose={() => setOpenSignIn(false)}
>
<Box sx={style}>
<form className="app__signup">
<center>
<img
className="app__headerImage"
src="https://www.instagram.com/static/images/web/mobile_nav_type_logo.png/735145cfe0a4.png"
alt="HeaderImage"
/>
</center>
<Input
type="text"
placeholder="email"
defaultValue={email}
onChange={(e) => setEmail(e.target.value)}
/>
<Input
type="text"
placeholder="password"
defaultValue={password}
onChange={(e) => setPassword(e.target.value)}
/>
<center>
<Button type="submit" onClick={signin}>SignIn</Button>
</center>
</form>
</Box>
</Modal>
<h1>TEST</h1>
{/* header */}
{
posts.map(({ id, post }) => (
<Post username={post.username} caption={post.caption} imageUrl={post.imageUrl} />
))
}
{/* post */}
{/* post */}
</div >
);
}
export default App;
Here↓ is ImageUpload.js which I got firebase is not defined when I erase the? mark from ImageUpload tag,,,,
firebase is not defined from this line↓
timestamp: firebase.firestore.FieldValue.serverTimestamp(),
ImageUpload.js
import React, { useState } from 'react';
import Button from '#mui/material/Button';
import { storage, db } from "./firebase";
import firebase from 'firebase/app';
function ImageUpload(username) {
const [image, setImage] = useState(null);
const [url, setUrl] = useState("");
const [progress, setProgress] = useState(0);
const [caption, setCaption] = useState('');
const handleChange = (e) => {
if (e.target.files[0]) {
setImage(e.target.files[0])
}
};
const handleUpload = () => {
const uploadTask = storage.ref('images/${image.name}').put(image);
uploadTask.on(
"state_change",
(snapshot) => {
//progress function
const progress = Math.round(
(snapshot.bytesTransferred / snapshot.totalBytes) * 100
);
setProgress(progress);
},
(error) => {
//error function
console.log(error);
alert(error.message);
},
() => {
//complete func
storage
.ref("images")
.child(image.name)
.getDownloadURL()
.then(url => {
//post image inside DB
db.collection("posts").add({
timestamp: firebase.firestore.FieldValue.serverTimestamp(),
caption: caption,
imageUrl: url,
username: username
});
setProgress(0);
setCaption("");
setImage(null);
})
}
)
}
return (
<div>
{/* I want to have .... */}
{/* caption input */}
{/* file picker */}
{/* Post button */}
<progress value={progress} max="100" />
<input type="text" placeholder="enter a caption.." onChange={event => setCaption(event.target.value)} />
<input type="file" onChange={handleChange} />
<Button onClick={handleUpload}>
upload
</Button>
</div >
)
}
export default ImageUpload
To be safe here ↓ is firebase.js(privacy info are shown as ***)
firebase.js
import firebase from "firebase";
const firebaseApp = firebase.initializeApp({
apiKey: "***",
authDomain: "***.firebaseapp.com",
projectId: "***",
storageBucket: "***.appspot.com",
messagingSenderId: "*****",
appId: "****",
measurementId: "****"
})
const db = firebase.firestore();
const auth = firebase.auth();
const storage = firebase.storage();
export { db, auth, storage };
And index.js
index.js
import React from 'react';
import ReactDOM from 'react-dom';
import './index.css';
import App from './App';
import reportWebVitals from './reportWebVitals';
ReactDOM.render(
<React.StrictMode>
<App />
</React.StrictMode>,
document.getElementById('root')
);
reportWebVitals();
Moreover, firebase version is 8.10.0, using MacBook air intel one OS BigSur
Hey I am trying to covert a class component into a functional component and for some reason the props I'm passing into the form component are being passed as object values. The original class component works fine but I am not sure what is causing this issue with props. what it looks like with
what it should look like with class component:
what I currently have with functional component:
function component home page
import React from "react";
// import Jumbotron from "react-bootstrap/Jumbotron";
import Row from "react-bootstrap/Row";
import Card from "../components/Card";
import Form from "../components/Form";
import Col from "react-bootstrap/Col";
import Container from "react-bootstrap/Container";
import Jumbotron from "react-bootstrap/Jumbotron";
import { useState } from "react";
import API from "../utils/API";
import Book from "../components/Book";
import Button from "react-bootstrap/Button";
import { List } from "../components/List";
import Footer from "../components/Footer";
import "./style.css";
export default function Home() {
let [books, setBooks] = useState([]);
let [q, setQ] = useState("");
let [message, setMessage] = useState("Search For A Book to Begin");
// const handleInputChange = (event) => {
// let { name, value } = event.target;
// setQ(([name] = value));
// };
const handleInputChange = (event) => {
setQ(event.target.value)
};
let getBooks = () => {
API.getBooks(q)
.then((res) => setBooks(res.data))
.catch(() => setBooks([]));
setMessage("No New Books Found, Try a Different Query");
};
const handleFormSubmit = (event) => {
event.preventDefault();
getBooks();
};
let handleBookSave = (id) => {
const book = books.find((book) => book.id === id);
API.saveBook({
googleId: book.id,
title: book.volumeInfo.title,
subtitle: book.volumeInfo.subtitle,
link: book.volumeInfo.infoLink,
authors: book.volumeInfo.authors,
description: book.volumeInfo.description,
image: book.volumeInfo.imageLinks.thumbnail,
}).then(() => getBooks());
};
return (
<div>
<Container>
<Row>
<Col md={12}>
<Jumbotron className="rounded-3 mt-4">
<h1 className="text-center ">
<strong>(React) Google Books Search</strong>
</h1>
<h2 className="text-center">
Search for and Save Books of Interest.
</h2>
</Jumbotron>
</Col>
<Col md={12}>
<Card title="Book Search" icon=" fa-book">
<Form
handleInputChange={handleInputChange}
handleFormSubmit={handleFormSubmit}
q={q}
/>
</Card>
</Col>
</Row>
<Row>
<Col md={12}>
<Card title="Results">
{books.length ? (
<List>
{books.map((book) => (
<Book
key={book.id}
title={book.volumeInfo.title}
subtitle={book.volumeInfo.subtitle}
link={book.volumeInfo.infolink}
authors={book.volumeInfo.authors.join(", ")}
description={book.volumeInfo.description}
image={book.volumeInfo.imageLinks.thumbnail}
Btn={() => (
<Button
onClick={() => handleBookSave(book.id)}
variant="primary"
className="ml-2"
>
Save
</Button>
)}
/>
))}
</List>
) : (
<h2 className="text-center">{message}</h2>
)}
</Card>
</Col>
</Row>
<Footer />
</Container>
</div>
);
}
Form component
import React from "react";
function Formmy({q, handleInputChange, handleFormSubmit }) {
return (
<form>
<div className="form-group">
<label htmlFor="Query">
<strong>Book</strong>
</label>
<input
className="form-control"
id="Title"
type="text"
value={q}
placeholder="Ready Player One"
name="q"
onChange={handleInputChange}
required
/>
</div>
<div className="float-end">
<button
onClick={handleFormSubmit}
type="submit"
className="btn btn-lg btn-danger float-right"
>
Search
</button>
</div>
</form>
);
}
export default Formmy;
I am trying to use a container to simplify some styling while learning React and I am having some issues.
Currently this is my Component
import React from 'react'
import { Container, Row, Col } from 'react-bootstrap'
const FormContainer = ({ childern }) => {
return (
<Container>
<Row className="justify-content-md-center">
<Col xs={12} md={6}>
{childern}
</Col>
</Row>
</Container>
)
}
export default FormContainer
And this is where I am loading it into
import React, { useState, useEffect } from 'react'
import { Link } from 'react-router-dom'
import { Form, Button, Row, Col } from 'react-bootstrap'
import { useDispatch, useSelector } from 'react-redux'
import Message from '../components/Message'
import Loader from '../components/Loader'
import FormContainer from '../components/FormContainer'
import { login } from '../actions/userActions'
const LoginScreen = ({location, history}) => {
const [email, setEmail] = useState('')
const [password, setPassword] = useState('')
const dispatch = useDispatch()
const userLogin = useSelector(state => state.userLogin)
const {loading, error, userInfo} = userLogin
const redirect = location.search ? location.search.split('=')[1] : '/' // Takes location of Url, splits after the equals sign, and everything right of it or takes us back to '/'
useEffect(()=> {
if(userInfo) {
history.push(redirect)
}
}, [history, userInfo, redirect])
const submitHandler = (e) => {
e.preventDefault()
dispatch(login(email, password))
}
return (
<FormContainer>
<h1>Sign In</h1>
{error && <Message variant='danger'>{error}</Message>}
{loading && <Loader/>}
<Form onSubmit={submitHandler}>
<Form.Group controlId='email'>
<Form.Label>Email Address</Form.Label>
<Form.Control type='email' placeholder="Enter email" value={email} onChange={(e) => setEmail(e.target.value)}>
</Form.Control>
</Form.Group>
<Form.Group controlId='password'>
<Form.Label>Password</Form.Label>
<Form.Control type='password' placeholder="Enter password" value={password} onChange={(e) => setPassword(e.target.value)}>
</Form.Control>
</Form.Group>
<Button type='submit' variant='primary'>
Sign In
</Button>
</Form>
<Row className='py-3'>
<Col>
New Customer <Link to={redirect ? `/register?redirect=${redirect}` : '/register'}>
Register
</Link>
</Col>
</Row>
</FormContainer>
)
}
export default LoginScreen
When I remove FormContainer and replace it with a div the LoginScreen info shows up but without the styling. Otherwise it is blank with no issues in the Console. My other components seem to to show some stuff, but not the text.
Any help would be amazing.
Thanks!
I'm starting to learn React and following the tutorial and got stuck with this error when I was trying to upload picture. When I press upload button, this error "Objects are not valid as a React child (found: object with keys {username}). If you meant to render a collection of children, use an array instead." shown up and I couldn't reload the page anymore.
Render Error
Here are the codes:
1.App.js
import React, { useEffect, useState } from "react";
import './App.css';
import Post from './Post';
import { auth, db } from "./firebase";
import Modal from '#material-ui/core/Modal';
import { makeStyles } from '#material-ui/core/styles';
import { Button, Input } from "#material-ui/core";
import ImageUpload from './ImageUpload';
function getModalStyle() {
const top = 50;
const left = 50;
return {
top: `${top}%`,
left: `${left}%`,
transform: `translate(-${top}%, -${left}%)`,
};
}
const useStyles = makeStyles((theme) => ({
paper: {
position: 'absolute',
width: 400,
backgroundColor: theme.palette.background.paper,
border: '2px solid #000',
boxShadow: theme.shadows[5],
padding: theme.spacing(2, 4, 3),
},
}));
function App() {
const classes = useStyles();
const [modalStyle] = React.useState(getModalStyle);
const [posts, setPosts] = useState([]);
const [open, setOpen] = useState(false);
const [openSignIn, setOpenSignIn] = useState('');
const [username, setUsername] = useState('');
const [email, setEmail] = useState('');
const [password, setPassword] = useState('');
const [user, setUser] = useState(null);
//UseEffect -> Run a piece of code based on a specific condition
useEffect(() => {
const unsubscribe = auth.onAuthStateChanged((authUser) => {
if (authUser) {
//user has logged in...
console.log(authUser);
setUser(authUser);
} else {
//user has logged out...
setUser(null);
}
return () => {
//perform some cleanup action
unsubscribe();
}
})
}, [user, username]);
useEffect(() => {
//this is where the code runs
db.collection('posts').onSnapshot(snapshot => {
//everytime a new post is added, this code fires...
setPosts(snapshot.docs.map(doc => ({
id: doc.id,
post: doc.data()
})));
})
}, []);
const signUp = (event) => {
event.preventDefault();
auth
.createUserWithEmailAndPassword(email, password)
.then((authUser) => {
return authUser.user.updateProfile({
displayName: username
})
})
.catch((error) => alert(error.message))
}
const signIn = (event) => {
event.preventDefault();
auth
.signInWithEmailAndPassword(email, password)
.catch((error) => alert(error.message))
setOpenSignIn(false);
}
return (
<div className="app">
{user?.displayName ? (
<ImageUpload username={user.displayName} />
) : (
<h3>Sorry you need to login to upload</h3>
)}
<Modal
open={open}
onClose={() => setOpen(false)}
>
<div style={modalStyle} className={classes.paper}>
<form className="app__signup">
<center>
<img
className="app__headerImage"
src="https://www.instagram.com/static/images/web/mobile_nav_type_logo.png/735145cfe0a4.png"
alt=""
/>
</center>
<Input
placeholder="username"
type="text"
value={username}
onChange={(e) => setUsername(e.target.value)}
/>
<Input
placeholder="email"
type="text"
value={email}
onChange={(e) => setEmail(e.target.value)}
/>
<Input
placeholder="password"
type="password"
value={password}
onChange={(e) => setPassword(e.target.value)}
/>
<Button type="submit" onClick={signUp}>Sign Up</Button>
</form>
</div>
</Modal>
<Modal
open={openSignIn}
onClose={() => setOpenSignIn(false)}
>
<div style={modalStyle} className={classes.paper}>
<form className="app__signup">
<center>
<img
className="app__headerImage"
src="https://www.instagram.com/static/images/web/mobile_nav_type_logo.png/735145cfe0a4.png"
alt=""
/>
</center>
<Input
placeholder="email"
type="text"
value={email}
onChange={(e) => setEmail(e.target.value)}
/>
<Input
placeholder="password"
type="password"
value={password}
onChange={(e) => setPassword(e.target.value)}
/>
<Button type="submit" onClick={signIn}>Sign In</Button>
</form>
</div>
</Modal>
<div className="app__header">
<img
className="app__headerImage"
src="https://www.instagram.com/static/images/web/mobile_nav_type_logo.png/735145cfe0a4.png"
alt="" />
</div>
{user ? (
<Button onClick={() => auth.signOut()}>Logout</Button>
) : (
<div className="app__loginContainer">
{/* : is stand for OR */}
<Button onClick={() => setOpenSignIn(true)}>Sign In</Button>
<Button onClick={() => setOpen(true)}>Sign Up</Button>
</div>
)}
<h1>Hello Joes! Let's build an Instagram CLone with React</h1>
{
posts.map(({ id, post }) => (
<Post key={id} username={post.username} caption={post.caption} imgUrl={post.imgUrl} />
))
}
</div>
);
}
export default App;
Here is the ImageUpload file
2. ImageUpload.js
import { Button } from '#material-ui/core'
import React, { useState } from 'react';
import { storage, db } from './firebase';
import firebase from "firebase";
function ImageUpload(username) {
const [image, setImage] = useState(null);
const [progress, setProgress] = useState(0);
const [caption, setCaption] = useState('');
const handleChange = (e) => {
if (e.target.files[0]) {
setImage(e.target.files[0]);
}
};
const handleUpload = () => {
const uploadTask = storage.ref(`images/${image.name}`).put(image);
uploadTask.on(
"state_change",
(snapshot) => {
//progress funtion...
const progress = Math.round(
(snapshot.bytesTransferred / snapshot.totalBytes) * 100
);
setProgress(progress);
},
(error) => {
//Error function...
console.log(error);
alert(error.message);
},
() => {
// Complete function...
storage
.ref("images")
.child(image.name)
.getDownloadURL()
.then(url => {
// Post image on db
db.collection("posts").add({
timestamp: firebase.firestore.FieldValue.serverTimestamp(),
caption: caption,
imageUrl: url,
username: username
});
setProgress(0);
setCaption("");
setImage(null);
});
}
);
};
return (
<div>
{/* I want to have... */}
{/* Caption input */}
{/* File picker */}
{/* Post button */}
<progress value={progress} max="100" />
<input type="text" placeholder="Enter a caption..." onChange={event => setCaption(event.target.value)} value={caption} />
<input type="file" onChange={handleChange} />
<Button onClick={handleUpload}>
Upload
</Button>
</div>
)
}
export default ImageUpload
Thanks guys!
This line is wrong:
<progress value={progress} max="100" />
React components have to be upper case.
Your progress is a number, not a React component
You probably wanted to import the component Progress and write:
<Progress value={progress} max="100" />
I have a react native app with expo-client and gives a too-many re-renders error I will post the files, notice that I use react-native-paper.
This is App.js which is a wrapper for app
import React from "react";
import { Provider as PaperProvider, DefaultTheme } from "react-native-paper";
import { StatusBar } from "expo-status-bar";
import Homescreen from "./views/screens/homescreen";
//import { SafeAreaView, Text } from "react-native";
export default function App() {
return (
<PaperProvider theme={theme}>
<Homescreen />
<StatusBar />
</PaperProvider>
);
}
const theme = {
...DefaultTheme,
};
This is the homescreen which is a wrapper for login and sign up components
import React from "react";
import { View } from "react-native";
import { NavigationContainer } from "#react-navigation/native";
import { createStackNavigator } from "#react-navigation/stack";
import SignUp from "../components/signup";
import Login from "../components/login";
import { Button } from "react-native-paper";
export default function Homescreen({ navigation }) {
const Stack = createStackNavigator();
return (
<View>
<Button onPress={() => navigation.navigate("SignUp")}>SignUp</Button>
<Button onPress={() => navigation.navigate("LogIn")}>Login</Button>
<NavigationContainer>
<Stack.Navigator>
<Stack.Screen name="SignUp" component={SignUp} />
<Stack.Screen name="LogIn" component={Login} />
</Stack.Navigator>
</NavigationContainer>
</View>
);
}
There are sign up and login components which are very identical
import React, { useState } from "react";
import { View } from "react-native";
import { TextInput, Button } from "react-native-paper";
export default function SignUp() {
const [email, setEmail] = useState("");
const [password, setPassword] = useState("");
const signUp = (t1, t2) => {
setEmail("");
setPassword("");
};
const changeEmailHandler = (e) => {
setEmail(e.target.value);
};
const changePasswordHandler = (e) => {
setPassword(e.target.value);
};
return (
<View>
<TextInput
mode="outlined"
left
label="email"
placeholder="Enter your email: "
onChangeText={changeEmailHandler}
value={email}
/>
<TextInput
mode="outlined"
left
label="password"
placeholder="Enter your password: "
onChangeText={changePasswordHandler}
value={password}
type="password"
/>
<Button
icon="arrow-right-alt"
mode="contained"
onClick={signUp(email, password)}
>
Join us now
</Button>
</View>
);
}
import React, { useState } from "react";
import { View } from "react-native";
import { TextInput, Button } from "react-native-paper";
export default function Login() {
const [email, setEmail] = useState("");
const [password, setPassword] = useState("");
const logIn = (t1, t2) => {
setEmail("");
setPassword("");
};
const changeEmailHandler = (e) => {
setEmail(e.target.value);
};
const changePasswordHandler = (e) => {
setPassword(e.target.value);
};
return (
<View>
<TextInput
mode={outlined}
left
label="email"
placeholder="Enter your email: "
onChangeText={changeEmailHandler}
value={email}
/>
<TextInput
mode={outlined}
left
label="password"
placeholder="Enter your password: "
onChangeText={changePasswordHandler}
value={password}
type="password"
/>
<Button
icon="arrow-right-alt"
mode="contained"
onClick={logIn(email, password)}
></Button>
</View>
);
}
This is the appbar component
import React from "react";
import { View } from "react-native";
import { Appbar } from "react-native-paper";
export default function CustomAppBar() {
return (
<View>
<Appbar>
<Appbar.Header>
<Appbar.Content title="Date Planner" />
</Appbar.Header>
</Appbar>
</View>
);
}
The onClick event in the <Button> is the problem. It calls signUp(email, password) on every render which causes an infinite loop because inside there is a call for setPassword. Instead in onClick you can pass a callback, see my suggestion below.
You need to modify your button as:
<Button
icon="arrow-right-alt"
mode="contained"
onClick={() => signUp(email, password)}
>
Join us now
</Button>
In this way the signUp function will be called only on click event.
Based on the comment also needs to change onClick={logIn(email, password)} as well similarly as suggested above.