#javascript #reactjs
#javascript #reactjs
Вопрос:
Я начинаю изучать React и следую руководству и застрял с этой ошибкой, когда пытался загрузить изображение. Когда я нажимаю кнопку загрузки, появляется эта ошибка «Объекты недопустимы в качестве дочернего элемента React (найдено: объект с ключами {имя пользователя}). Если вы хотели отобразить коллекцию дочерних элементов, вместо этого используйте массив.» появилось сообщение, и я больше не мог перезагружать страницу. Ошибка рендеринга Вот коды:
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;
Вот файл ImageUpload
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
Спасибо, ребята!
Комментарии:
1. Вы забыли разместить здесь все содержимое вашего
node_modules
каталога2. Этот вопрос слишком многословен (в данном случае более чем уместен). Вы должны удалить ненужный код, чтобы его было легче читать и было больше шансов, что кто-нибудь захочет ответить.
Ответ №1:
Эта строка неверна:
<progress value={progress} max="100" />
- Компоненты React должны быть прописными.
- Your
progress
— это число, а не компонент React
Вероятно, вы хотели импортировать компонент Progress
и написать:
<Progress value={progress} max="100" />