Мое приложение состоит из следующего: Это приложение, использующее стек MERN, цель которого - предоставить пользователям возможность входить в систему, регистрироваться и просматривать контакты. (Это просто для практики, у меня нет планов по его развертыванию).
Проблема возникает, когда Пользователь входит в систему, а затем переходит к контактам, я могу их console.log, получая их из Express в задней части, но я не могу их отобразить. Вдобавок ко всему, когда я console.log длину, он говорит 0, хотя когда я console.log массив, он показывает элементы, и это то, что я не могу понять.
Вот приложение. js
// Importing React
import React from 'react';
// Importing the Router
import { BrowserRouter as Router, Switch, Route} from "react-router-dom";
// Get Login Functional Component
import Register from "./Register";
// Get the Register FC
import LogIn from "./LogIn";
// Get the Contacts FC
import Contacts from "./Contacts";
// Get the USER Context
import {UserContextProvider} from "./Context/UserContext";
function App() {
return (
<UserContextProvider>
<Router>
<div className="App">
<Switch>
<Route exact path="/register" component={Register} />
<Route exact path="/login" component={LogIn} />
<Route exact path="/contacts" component={Contacts} />
</Switch>
</div>
</Router>
</UserContextProvider>
);
}
export default App;
Как видите, я использую React Router, и вот, во-первых, регистр. js
import React, {useState} from 'react';
import axios from "axios";
import {Link} from "react-router-dom";
function Register() {
// Getting Email Input with UseState
const [email, setEmail] = useState("");
// Getting Password Input with UseState
const [password, setPassword] = useState("");
// Getting Confirmation Password Input with UseState
const [confirmationPassword, setConfirmationPassword] = useState("");
// If passwords are matching
const [passwordsMatch, setPasswordsMatch] = useState("");
// To Clear Input Fields
const clearFields = () => {setEmail(""); setPassword("");}
// Function that changes the email state when the user types
const changeEmail = (e) => {
setEmail(e.target.value);
}
// Function that changes the password state when the user types
const changePassword = (e) => {
setPassword(e.target.value);
}
// Function that changes the confirmation password state when the user types
const changeConfirmationPassword = (e) => {
setConfirmationPassword(e.target.value);
}
// When the user submits the form
const registerSubmit = (e) => {
// So it doesn't go to another page
e.preventDefault();
if (password === confirmationPassword) {
setPasswordsMatch(true);
// Passing data to backend
axios.post("http://localhost:5000/post", {email, password})
.then(response => console.log(response))
.catch(error => console.log(error.data));
// Clear all the fields
clearFields();
} else {
setPasswordsMatch(false);
}
}
return (
<div>
<div className="container mt-4">
<form onSubmit={(e) => registerSubmit(e)}>
<div className="form-group">
<label htmlFor="exampleInputEmail1">Email address</label>
<input type="email" className="form-control" onChange={(e) => changeEmail(e)} id="exampleInputEmail1" aria-describedby="emailHelp" placeholder="Enter email" value={email}></input>
<small id="emailHelp" className="form-text text-muted">We'll never share your email with anyone else.</small>
</div>
<div className="form-group">
<label htmlFor="exampleInputPassword1">Password</label>
<input onChange={(e) => changePassword(e)} type="password" className="form-control" id="exampleInputPassword1" placeholder="Password" value={password}></input>
</div>
<div className="form-group">
<label htmlFor="exampleInputPassword2">Confirm Password</label>
<input onChange={(e) => changeConfirmationPassword(e)} type="password" className="form-control" id="exampleInputPassword12" placeholder="Password" value={confirmationPassword}></input>
{/* If Passwords Match then Show Alert */}
{passwordsMatch === false &&
<div className="alert alert-danger mt-4" role="alert">
Passwords don't match!
</div>
}
</div>
<button type="submit" className="btn btn-primary">Register</button>
</form>
<h5 className="mt-4 mb-4">If you already have an account</h5>
<Link to={"/login"} className="btn btn-secondary">I already have an account</Link>
</div>
</div>
)
}
export default Register;
Вот логин. js:
import React, {useState, useContext, history} from 'react';
import {Link} from "react-router-dom";
import axios from "axios";
// Get User Context
import {UserContext} from "./Context/UserContext";
function LogIn() {
// Getting the ID from the context
const {id, setId} = useContext(UserContext);
// Getting Email Input with UseState
const [email, setEmail] = useState("");
// Getting Password Input with UseState
const [password, setPassword] = useState("");
const [logIn, setLogIn] = useState(undefined);
// Function that changes the email state when the user types
const changeEmail = (e) => {
setEmail(e.target.value);
}
// Function that changes the password state when the user types
const changePassword = (e) => {
setPassword(e.target.value);
}
// When the user submits the form
const onLoginSubmit = (e) => {
// So it doesn't go to another page
e.preventDefault();
// Check Credentials
axios.get("http://localhost:5000")
.then(response => { for (const index in response.data) {
const person = response.data[index];
if (person.email === email && person.password === password) {
// User has succesfully logged in
setLogIn(true);
// Store Secret ID in variable
const secretID = person._id;
// Change Context
setId(secretID);
// Break the loop
break;
} else {
setLogIn(false);
}
};
})
.catch(error => console.log(error.data));
}
return (
<div>
<div className="container mt-4">
<form onSubmit={(e) => onLoginSubmit(e)}>
<div className="form-group">
<label htmlFor="exampleInputEmail1">Email address</label>
<input type="email" className="form-control" onChange={(e) => changeEmail(e)} id="exampleInputEmail1" aria-describedby="emailHelp" placeholder="Enter email" value={email}></input>
<small id="emailHelp" className="form-text text-muted">We'll never share your email with anyone else.</small>
</div>
<div className="form-group">
<label htmlFor="exampleInputPassword1">Password</label>
<input onChange={(e) => changePassword(e)} type="password" className="form-control" id="exampleInputPassword1" placeholder="Password" value={password}></input>
</div>
<button type="submit" className="btn btn-primary">Log In</button>
</form>
{logIn === false &&
<div className="alert alert-danger mt-4" role="alert">
Wrong credentials!
</div>
}
{logIn === true &&
<div className="alert alert-success mt-4" role="alert">
Correct information!
</div>
}
<h5 className="mt-4 mb-4">If you don't have an account</h5>
<Link to={"/register"} className="btn btn-secondary">I don't have an account</Link>
{logIn && <Link to={"/contacts"} className="btn btn-secondary ml-4">Contacts</Link>}
</div>
</div>
)
}
export default LogIn;
Здесь вы можете видеть, что я использую Context Hook, вот файл, в котором я его создаю (UserContext. js):
import React, {createContext, useState} from 'react'
export const UserContext = createContext();
export function UserContextProvider(props) {
// Create the ID variable
const [id, setId] = useState("");
return (
<UserContext.Provider value={{id, setId}}>
{props.children}
</UserContext.Provider>
)
}
И, наконец, вот my Contact. js:
import React, {useContext, useState} from 'react';
import {UserContext} from "./Context/UserContext";
import axios from "axios";
// To display single contacts
import SingleContact from "./SingleContact";
function Contacts() {
const {id, setId} = useContext(UserContext);
const [email, setEmail] = useState("");
const contacts = [];
// Get User's Info from database
// Check Credentials
axios.get("http://localhost:5000/contacts")
.then(response => { for (const index in response.data) {
const contact = response.data[index];
if (contact.id === id) {
contacts.push(contact);
}
};
})
.catch(error => console.log(error.data));
return (
<div>
<h1>Contacts</h1>
{console.log(contacts)}
{console.log(contacts.length)}
{contacts.forEach(contact => <h1>{contact}</h1>)}
</div>
)
}
export default Contacts
Здесь forEach l oop не работает, и я понятия не имею, почему, потому что, когда я печатаю массив контактов, я получаю их полностью.
Вот что получаю в консоли:
Результаты console.logging массива контактов и его длина
Я не предоставляю файлы из бэкэнда, потому что, как вы можете видеть, проблема явно во внешнем интерфейсе, потому что я получаю данные, но не отображаю их правильно.