After adding router in App.js in react nothing is displayed in the webpage - node.js

After using the BrowserRouter as a wrapper function nothing is displayed on the webpage.
App.js
import React, { Component } from 'react';
import './App.css';
import Homepage from './components/homepage/homepage';
import Login from './components/login/login';
import Register from './components/register/register';
import { BrowserRouter as Router, Routes, Route, Link } from 'react-router-dom';
function App() {
return (
// <div className="App">
<Router>
<div className="App">
<ul >
<li>
<Link to="/">Home</Link>
</li>
<li>
<Link to="/login">Login</Link>
</li>
<li>
<Link to="/register">Register</Link>
</li>
</ul>
<Routes>
<Route exact path='/' element={< Homepage />}></Route>
<Route exact path='/login' element={< Login />}></Route>
<Route exact path='/register' element={< Register />}></Route>
</Routes>
</div>
</Router>
// </div>
);
}
export default App;
homepage.js
import React from "react"
import "./homepg.css"
const Homepage = () => {
return (
<div className="homepage">
<h1>Hello Homepage</h1>
<div className="button">Logout</div>
</div>
)
}
export default Homepage
login.js
import React, {useState} from "react"
import "./login.css"
import axios from "axios"
const Login = () => {
const [ user, setUser ] = useState({
email : "",
password : ""
})
const handleChange = e => {
const {name , value} = e.target
setUser({
...user,
[name] : value
})
}
const login = () => {
axios.post("http://localhost:9002/login",user)
.then(res => alert(res.data.message))
}
return (
<div className="login">
{console.log("User",user)}
<h1>Login</h1>
<input type="text" name="email" value={user.email} placeholder="Enter email" onChange={handleChange}></input>
<input type="password" name="password" value={user.password} placeholder="Enter password" onChange={handleChange}></input>
<div className="button" onClick={login}>Login</div>
<div>or</div>
<div className="button">Register</div>
</div>
)
}
export default Login
register.js
import React, {useState} from "react"
import "./register.css"
import axios from "axios"
const Register = () => {
const [ user, setUser ] = useState({
name: "",
email : "",
password : "",
reEnterPassword : ""
})
const handleChange = e => {
const {name , value} = e.target
setUser({
...user,
[name] : value
})
}
const register = () =>{
const {name,email,password, reEnterPassword} = user
if(name && email && password && (password === reEnterPassword)){
axios.post("http://localhost:9002/register", user)
// console.log("yo")
.then(res => console.log(res))
}
else{
alert("Invalid input")
}
}
return (
<div className="register">
{console.log("User",user)}
<h1>Register</h1>
<input type="text" name="name" value={user.name} placeholder="Your Name" onChange={handleChange}></input>
<input type="text" name="email" value={user.email} placeholder="Your Email" onChange={handleChange}></input>
<input type="password" name="password" value={user.password} placeholder="Your password" onChange={handleChange}></input>
<input type="password" name="reEnterPassword" value={user.reEnterPassword} placeholder="Re-enter password" onChange={handleChange}></input>
<div className="button" onClick={register}>Register</div>
<div>or</div>
<div className="button">Login</div>
</div>
)
}
export default Register
index.js
import React from 'react';
import ReactDOM from 'react-dom/client';
import './index.css';
import App from './App';
const root = ReactDOM.createRoot(document.getElementById('root'));
root.render(
<App />,
);
If only <Homepage />, <Login/>, and <Register /> are present then homepage, login, and register page gets displayed.
But once I use the Router from react-router-dom then the webpage is blank, nothing is displayed.

There are several reasons why your components are not being displayed when using the BrowserRouter component from the react-router-dom library. Some of the most common reasons include:
1. Incorrect Router Import: Make sure you have imported the BrowserRouter component correctly from the react-router-dom library. The correct import statement is: import { BrowserRouter } from 'react-router-dom'.
2. Wrapping the Wrong Components: Make sure that you are wrapping the correct components inside the BrowserRouter. The BrowserRouter should wrap all the components that need access to the routing functionality.
3. Incorrect Route Configuration: Make sure you have correctly set up your routes using the Route component. The Route component should be used to define the mapping between a path and a component.
4. Components not Exporting Correctly: Make sure that your components are being exported correctly. Each component should be exported using export default ComponentName.
If you provide more information about your code and the error message that you're encountering, I'd be happy to help you further.

Related

how to post form data to the server backend

Form.js
import "./form.css";
import React, {useEffect,useState} from "react";
import {addBeauty,deleteB} from "./beauty";
import Modal from "./Modal";
import axios from 'axios';
export default function CreateForm() {
const [Name, setName] = useState("");
const [Intro, setIntro] = useState("");
const [isOpen, setIsOpen] = useState();
const [backendData, setBackendData] = useState([{}]);
useEffect(()=>{
fetch("http://localhost:5000/api").then(
response=>response.json()
).then(
data=>{ setBackendData(data)}
)
},[]);
const handleSubmit = (event)=>{
event.preventDefault();
axios.post("http://localhost:5000/api",{
id: userList[userList.length - 1].id + 1, Name:Name, Introduction:Intro
}).then(res=>{
console.log(res.data);
})
}
return (
<div className="container">
<form className="add" onSubmit={handleSubmit} >
<h2>User</h2>
<label htmlFor= "name">Name</label>
<input type="text" value={Name}
onChange={(event) => {setName(event.target.value);}}/>
<label htmlFor= "Intro">Introduction</label>
<input type="text" value={Intro}
onChange={(event) => {setIntro(event.target.value);}}/>
<p></p>
<p></p>
<div className = "press">
<button id = "1" type="submit">
Add Beauty
</button>
<button id = "2"
onClick={clearForm}
>
Clear Form
</button>
</div>
</form>
<br></br>
<br></br>
<br></br>
<div className="display">
{(typeof userData.user1 === 'undefined')?(
<h1>Loading</h1>):(
backendData.user1.map((user,i)=>{
return (
<div>
<h1> {user.Name}</h1>
<button onClick={()=>{
setIsOpen(user.id);
}}>View in popup</button>
<Modal open={isOpen === user.id} onClose={()=>setIsOpen(undefined)}>
<h3> {User.Introduction}</h3>
</Modal>
</div>
);})
)}
</div>
</div>
);
}
Server.js
const express = require('express');
const app = express();
const cors=require("cors");
const corsOptions ={
origin:'*',
credentials:true, //access-control-allow-credentials:true
optionSuccessStatus:200,
}
app.use(cors(corsOptions)) // Use this after the variable declaration
app.get("/api",(req,res)=> {
res.json({"user1":[
{
id: 1,
Name: "Isabella",
},
{
id:2,
Name: "Catalina
}
]})
});
app.listen(5000,()=>{
console.log("Server started on port 5000");
})
I create a from using react. And I try to send the formdata to backend and insert the formdata into the data stored at backend using axios.post. But it doesn't work. I know it's because I didn't add the prefix of backend data "user1" in axios.post. But I am not sure how to do that. Could anyone help me with this?
You have not created the route on the server correctly. You have opened a route for GETting "/api" but you need to open a route for POSTing
Replace this line:
app.get("/api",(req,res)=> {
with
app.post("/api",(req,res)=> {
Hi Here you need to create one route for post API as below
app.post("/api",(req,res)=> {
console.log(req.body) //here you got the requested data.
res.send("Success !");
});

Using axios post response in the jsx react

I want to take the data response from the Axios post, and display it on the page:
import React, { useRef} from 'react';
import logo from './assets/img/lupa.png';
import { Form } from "#unform/web";
import Input from './components/forms/input';
import * as Yup from "yup";
import './App.css';
import axios from 'axios';
function App() {
const formRef = useRef(null);
async function handleSubmit(data, ){
try{
const schema = Yup.object().shape({
nn: Yup.number().min(8,"O campo eh obrigatorio e precisa ter 8 ou mais caracteres")
})
await schema.validate(data)
console.log(data)
}catch(err){
if(err instanceof Yup.ValidationError){
console.log(err)
}}
axios.post("http://localhost:8080/api", data).then(res => console.log(res.data))
.catch(err => console.log(err));
}
return (
<div className="App">
<div className="App-header">
<img src={logo} className="App-logo" alt="logo" />
<h2>$ Search $</h2>
</div>
<Form ref={formRef} onSubmit={handleSubmit}>
<Input name="nn" type="number"/>
<button type='submit'>buscar</button>
</Form>
</div>
);
}
export default App;
But I don't know how to work with that res.data and how to display it on the page by the jsx react, I tried to use useState and set it in the axios.post("http://localhost:8080/api", data).then(res => setState(res.data))
.catch(err => console.log(err)); - but when I console.log someState it brings an object null, i tried to display on the page using
return (
<div className="App">
<div className="App-header">
<img src={logo} className="App-logo" alt="logo" />
<h2>$ Search $</h2>
</div>
<Form ref={formRef} onSubmit={handleSubmit}>
<Input name="nn" type="number"/>
<button type='submit'>buscar</button>
</Form>
{
someState.length >=1 ? someState.map((some, idx) =>{
return <p key={idx}>{some.data}</p>
})
: ""
}
</div>
);
}
but nothing were display! ( If you have some suggestion to change of the overall code, you can answer too ), How can I fix this 2 problems ? I want to learn moreThe first object Im printing my input, to check if it are working, and the second object its what I recieved from the axios post response(.then(res => console.log(res.data), I want to display this object "resultado"
Object { nn: "00000000353" }
Object { ip: "200.1******", resultado: 961 }
​
ip: "200.1*****"
​
resultado: 961
​
<prototype>: Object { … }
See this nice post by digitalOcean How to use axios in ReactJs
https://www.digitalocean.com/community/tutorials/react-axios-react
Hope you got a lot of help from this post.

let variable reassigned but stay undefined (socket.io, node.js, react)

I am implementing a real time chat app using react and node but struggling with sending messages to the server. Below is my Chat component where socket connection with the server starts.
The problem is when I hit the send button, sendMsg runs and gives me an error TypeError: Cannot read property 'emit' of undefined. socket is assigned the return values of socketIOClient(ENDPOINT)inside useEffect but seems to stay undefined at the time of hitting the send button. I guess
Can someone please help me fix this?
import React, { useState, useEffect } from 'react';
import socketIOClient from "socket.io-client";
import Button from '#material-ui/core/Button';
import Box from '#material-ui/core/Box';
import Loading from './Loading';
import TextField from '#material-ui/core/TextField';
import { Container, Typography } from '#material-ui/core';
import { Fragment } from 'react';
import queryString from 'query-string';
import { Redirect } from 'react-router-dom';
const ENDPOINT = "http://localhost:4001";
const Chat = ({location}) =>{
const [msgList, setMsgList] = useState([]);
const [name, setName] = useState(null);
let socket;
useEffect(()=>{
const {name} = queryString.parse(location.search);
setName(name)
socket = socketIOClient(ENDPOINT);
socket.emit("setName", name)
if(socket){
socket.on("greeting", (data)=>{
setMsgList(msgList => [...msgList, {type: "server", msg:data}]);
console.log(msgList)
})
}
return()=>{
if(socket){
socket.disconnect();
}
}
},[location.search, name])
const sendMsg = (event)=>{
event.preventDefault();
console.log(socket)
socket.emit("message", {msg: event.target.message.value})
}
return (
<Fragment>
<Container >
<Box maxWidth="600px" height="100vh" marginX="auto" marginY="0" textAlign="center" position="relative">
<Box paddingY="15px">
<Typography variant="h4">Let's Chat!</ Typography>
</Box>
<Box>
{msgList.map((msgObj, index)=>{
return <p key={index + 1}>{msgObj.type}: {msgObj.msg}</p>
})}
</Box>
<Box position="absolute" bottom="0" left="0"width="100%" zIndex="10">
<form autoComplete="off" onSubmit={sendMsg}>
<TextField name="message" label="say something" variant="outlined" fullWidth />
<Button type="submit" color="secondary" fullWidth variant="contained">Send</Button>
</form>
</Box>
</Box>
</Container>
</Fragment>
);
}
export default Chat;

My react app (login form) doesn't work like a spa page

I used CRA to create simple Login form. I've set up database with mongoose and built crud with node.
I don't think it has anything to do with the backend.
My intention with this little boiler plate was:
(not logged in) -> landing page shows 'Welcome' with Home, sign in menu.
(logged in) -> landing page shows 'Welcome, name' with Home, MyPage menu.
Down below is Login.js.
import React, { useState } from "react";
import { Link } from "react-router-dom";
import axios from "axios";
import "../App.css";
function Login() {
const [Email, setEmail] = useState("");
const [Password, setPassword] = useState("");
const [Error, setError] = useState("");
const onEmailHandler = (e) => {
setEmail(e.currentTarget.value);
};
const onPasswordHandler = (e) => {
setPassword(e.currentTarget.value);
};
const onSubmitHandler = (e) => {
e.preventDefault();
const body = {
email: Email,
password: Password,
};
axios
.post("/api/users/login", body)
.then((response) => {
if (!response.data.token) {
setError(response.data.error);
} else {
window.location.replace("/");
//props.history.push("/");
}
})
.catch((e) => {
console.log(e);
});
};
return (
<div>
<div>
<form className="login_form">
<input
type="email"
placeholder="Email"
onChange={onEmailHandler}
value={Email}
/>
<br />
<input
type="password"
placeholder="Password"
onChange={onPasswordHandler}
value={Password}
/>
<br />
<button onClick={onSubmitHandler}>Login</button>
</form>
</div>
<div
style={{
marginTop: 14,
fontSize: 15,
color: "red",
fontFamily: "Arial",
fontWeight: "lighter",
}}
>
{Error}
</div>
<div className="register_button">
<Link to="/register">Sign Up</Link>
</div>
</div>
);
}
export default Login;
As you can see, when you are signed in properly you are thrown to the landing page.
landing page looks like this.
import React, { useState } from "react";
import "../App.css";
import axios from "axios";
function Landing() {
const [Nickname, setNickname] = useState("");
axios.get("/api/users/authenticate").then((response) => {
if (response.data.name) {
setNickname(response.data.name);
}
});
return Nickname === "" ? (
<div className="welcome_msg">
<h4>Welcome!</h4>
</div>
) : (
<div className="welcome_msg">
<h4>Welcome, {Nickname}!</h4>
</div>
);
}
export default Landing;
And most importantly, App.js looks like down below.
import React, { useEffect, useState } from "react";
import { Route, BrowserRouter, Link } from "react-router-dom";
import "./App.css";
import axios from "axios";
import Landing from "./components/Landing";
import Login from "./components/Login";
import MyPage from "./components/MyPage";
import Register from "./components/Register";
function App() {
const [IsLoggedIn, setIsLoggedIn] = useState(false);
axios.get("/api/users/authenticate").then(
(response) => {
if (response.data.email) {
setIsLoggedIn(true);
} else {
setIsLoggedIn(false);
}
console.log(IsLoggedIn);
}
//[IsLoggedIn]
);
return IsLoggedIn ? (
<BrowserRouter>
<nav className="navigate">
<Link to="/">Home</Link>
<Link to="/mypage">Mypage</Link>
<hr />
</nav>
<Route exact path="/" component={Landing} />
<Route path="/login" component={Login} />
<Route path="/mypage" component={MyPage} />
<Route path="/register" component={Register} />
</BrowserRouter>
) : (
<BrowserRouter>
<nav className="navigate">
<Link to="/">Home</Link>
<Link to="/login">Sign in</Link>
<hr />
</nav>
<Route exact path="/" component={Landing} />
<Route path="/login" component={Login} />
<Route path="/mypage" component={MyPage} />
<Route path="/register" component={Register} />
</BrowserRouter>
);
}
export default App;
The Router api/user/authenticate returns json with user information(email, name, token).
It's not like there's an error to the app, but I think maybe it's re-rendered too many times? It's slow and doesn't work like a spa page. I've checked the network tab and there seems to be too many requests (mostly authentication) whenever i go to Home or Mypage.
Stay safe, stay away from virus and please help :(
That's because the submit handler must be passed to the form itself as an onSubmit method instead of the onClick of the button.
<form className="login_form" onSubmit={onSubmitHandler}>
...
</form>

I am getting a Warning: A component is changing an uncontrolled input of type text to be controlled

I building a simple todo app using the MERN stack with router and able to get it going except the edit part. I have 3 routes, the "Todos" page where i use axios to get the data from my express server route. The "Add" page for create new todo and the "Edit" page for editing and deleting. Here's my todos page where each todo has a button that takes the id as a url parameter unto the Edit page.
That little pencil/paper icon on each todo is a button link that get's the ID on click. Here's my Edit page with the data.
The warning:
Here's my Todos page i'm using a custom hook to fetch the data from express server route:
import React from 'react';
import useGetAPI from '../custom_hooks/useGetAPI';
import Todo from './todo_item/Todo';
const Todos = () =>{
const data = useGetAPI('http://localhost:4000');
return (
<div className="page">
<div className="page-header">
<h1>Todo Lists</h1>
</div>
<div className="page-content">
<ul className="todo-list">
{
data.map((todo)=><Todo todo={todo} key={todo._id}/>)
}
</ul>
</div>
</div>
);
}
export default Todos;
Here's my custom hooks for fetching data - used in Todos.
import {useState,useEffect} from 'react';
import axios from 'axios';
const useGetAPI = (url)=>{
const [data,setData] = useState([]);
useEffect(()=>{
const fetchData = async ()=>{
const response = await axios.get(url);
const data = [...response.data];
const error = response.error;
if(error)
console.log(error)
else{
console.log(data);
setData(data);
}
};
fetchData();
},[url])
return data;
}
export default useGetAPI;
Here's my Edit Page
import React,{useState, useEffect, useContext, useCallback} from 'react';
import useGetApiWithParams from '../custom_hooks/useGetApiWithParams';
import {FaTelegramPlane} from 'react-icons/fa';
import axios from 'axios';
import { matchPath } from 'react-router'
const EditTodo = (props) =>{
const todoID = props.match.params.id;
const [todo,setTodo] = useState(null);
const responseData = useGetApiWithParams('http://localhost:4000/edit',todoID);
console.log(`Todo id: ${todoID}`);
/* Set default data from database */
useEffect(()=>{
setTodo(responseData);
},[responseData,setTodo]);
const [description,setDescription] = useState('');
const [responsible,setResponsible] = useState('');
const [priority,setPriority] = useState('');
const [completed,setCompleted] = useState(false);
const handleDescription = useCallback((e)=>{
setDescription(e.target.value);
},[setDescription]);
const handleResponsible = useCallback((e)=>{
setResponsible(e.target.value);
},[setResponsible]);
const handlePriority = useCallback((e)=>{
setPriority(e.target.value);
},[setPriority]);
const handleCompleted = useCallback((e)=>{
setCompleted(!completed);
},[completed,setCompleted])
const handleSubmit = useCallback((e)=>{
e.preventDefault();
console.log('Form submitted');
console.log(`Description ${description}`);
console.log(`Description ${responsible}`);
console.log(`Description ${priority}`);
console.log(`Description ${completed}`);
const updatedTodo = {
description,
responsible,
priority,
completed: false
}
axios.put(`http://localhost/4000/edit/${props.match.params.id}`, updatedTodo)
.then(res=>console.log(res.data))
.catch(function (error) {
console.log(error);
});
},[description,responsible,priority,completed,props.match.params.id]);
return (
<div className="page">
<div className="page-header">
<h1>Edit Todo</h1>
</div>
<div className="page-content">
<form id="edit-todo-form" className="todo-form" onSubmit={handleSubmit}>
<div className="form-group">
<label htmlFor="description">Description:</label>
<input id="description" type="text" className="form-control" onChange={handleDescription} value={responseData.description} />
</div>
<div className="form-group">
<label htmlFor="responsible">Responsible:</label>
<input id="responsible" type="text" className="form-control" onChange={handleResponsible} value={responseData.responsible} />
</div>
<div className="form-group">
<label htmlFor="priorities">Priorities:</label>
<div id="priorities" className="form-radios">
<label htmlFor="radio1" className="radio-label">
<input name="priorityOptions" type="radio" id="radio1" value={responseData.priority} checked={priority === 'Low'} onChange={handlePriority}/>
<span className="radiomark"></span>
<span className="radiotext">Low</span>
</label>
<label htmlFor="radio2" className="radio-label">
<input type="radio" id="radio2" value={responseData.priority} checked={priority === 'Medium'} onChange={handlePriority}/>
<span className="radiomark"></span>
<span className="radiotext">Medium</span>
</label>
<label htmlFor="radio3" className="radio-label">
<input type="radio" id="radio3" value={responseData.priority} checked={priority === 'High'} onChange={handlePriority}/>
<span className="radiomark"></span>
<span className="radiotext">High</span>
</label>
</div>
</div>
<div className="form-group">
<label htmlFor="todo_completed">Status:</label>
<div id="todo_completed">
<label htmlFor="checkcompleted" className="check-label">
<input type="checkbox" id="checkcompleted" value={responseData.completed} onChange={handleCompleted}/>
<span className="checkmark"></span>
<span className="checktext">Completed</span>
</label>
</div>
</div>
<div className="form-group">
<button type="submit" className="form-btn"><FaTelegramPlane />Save Changes</button>
</div>
</form>
</div>
</div>
);
}
export default EditTodo;
Here's my custom hook for fetching data based on the Todo ID i get from the url:
import { useState,useEffect } from 'react';
import axios from 'axios';
const useGetApiWithParams = (url,params)=>{
const [data,setData] = useState([]);
useEffect(()=>{
const fetchData = async ()=>{
const response = await axios.get(`${url}/${params}`);
const data = response.data;
const error = response.error;
if(error)
console.log(`Error: ${error}`)
else{
console.log(...data);
setData(...data);
}
};
fetchData();
},[url,params])
return data;
}
export default useGetApiWithParams;
And the url with id param from MongoDB:
How to solve this? I tried the placeholder and set it's value to the response data from api but it only works for text boxes, what about the radio buttons and checkboxes? They don't seem to set the default value. For example the radio button for setting the priority value={responseData.priority} doesn't set the value as you can see here:
What i would like to happen is: from the Todos page on clicking the edit button, the edit page with a form already filled with values based on the todo id from the url parameter and be able to edit the values as well. Need help, thanks!

Resources