Update List of users Table after POST fetch request - javascript

Good afternoon everyone. I have 2 pages: one responsible for displaying List of Users in the table (data comes from fetching), then on Add User button click opens a Modal window with Sign Up form. On submitting this form, data about a new user is sent to an api (fetch POST), then sign up form closes and then the List of Users table is supposed to be updated with a newly added user. I fail to figure out how to correctly perform this update. Simple getUser() call in handleUserFormSubmit function doesn't do the trick (table is not re-rendered). Thanks in advance for any help
// Sign-Up Form Component
import React, { useState, useEffect } from "react";
const SignUpForm = ({
isFormVisible,
setIsFormVisible,
userList,
getUsers,
}) => {
const [usernameList, setUsernameList] = useState([]);
const [username, setUsername] = useState("");
const [usertype, setUsertype] = useState("");
const [password, setPassword] = useState("");
const [verifyPassword, setVerifyPassword] = useState("");
const [isChecked, setIsChecked] = useState(true);
const getUsernameList = () =>
userList.forEach(({ username }) => usernameList.push(username));
useEffect(() => {
getUsernameList();
console.log(usernameList);
}, []);
const addNewUser = async () => {
try {
const response = await fetch(
"http://www.someapi.com/add",
{
method: "POST",
headers: {
Accept: "application/json",
"Content-Type": "application/json",
},
body: JSON.stringify({
username,
usertype,
password,
}),
}
);
const data = await response.json();
console.log(data);
} catch (error) {
console.error(error.message);
}
};
const handleUserFormSubmit = (e) => {
e.preventDefault();
addNewUser();
setIsFormVisible(false);
getUsers();
}
};
return (
<>
{isFormVisible && (
<div
className={`${
isFormVisible ? "modal-overlay show-modal" : "modal-overlay"
}`}
>
<div className="sign-up-container">
<div className="sign-up-header-container">
<h2>Sign Up</h2>
<p>Please fill in this form to create an acoount</p>
</div>
<form className="form" onSubmit={(e) => e.preventDefault()}>
<label htmlFor="username">Username</label>{" "}
<br />
<input
type="text"
placeholder="Enter username"
id="username"
name="username"
value={username}
required
onChange={(e) => {
setUsername(e.target.value.toLowerCase());
setIsNameProvided(true);
}}
/>
<br />
<label htmlFor="usertype">User type</label>{" "}
<br />
<select
name="usertype"
id="usertype-select"
required
onChange={(e) => {
setUsertype(e.target.value);
setIsTypeSelected(true);
}}
>
<option value=""></option>
<option value="instructor">instructor</option>
<option value="maintenance">maintenance</option>
</select>
<br />
<label htmlFor="password">Password</label>{" "}
<br />
<input
type="password"
placeholder="Enter password"
id="password"
name="password"
required
value={password}
onCopy={(e) => e.preventDefault()}
onPaste={(e) => e.preventDefault()}
onChange={(e) => {
setPassword(e.target.value);
setIsPasswordProvided(true);
}}
/>
<br />
<label htmlFor="rpassword">Repeat Password</label>{" "}
<br />
<input
type="password"
placeholder="Repeat"
id="rpassword"
name="rpassword"
required
value={verifyPassword}
onCopy={(e) => e.preventDefault()}
onPaste={(e) => e.preventDefault()}
onChange={(e) => {
setVerifyPassword(e.target.value);
setIsConfirmPasswordProvided(true);
}}
/>{" "}
<br />
<input
type="checkbox"
id="remember"
name="remember"
checked={isChecked}
onChange={() => setIsChecked(!isChecked)}
/>
<label htmlFor="remember">Remember me</label>
<p className="terms-privacy">
By creating an account you agree to our{" "}
Terms & Privacy
</p>
<div className="btn-container">
<button
type="button"
className="cancel-btn"
onClick={() => setIsFormVisible(false)}
>
CANCEL
</button>
<button
type="submit"
className="sign-up-btn"
onClick={(e) => handleUserFormSubmit(e)}
>
SIGN UP
</button>
</div>
</form>
</div>
</div>
)}
</>
);
};
export default SignUpForm;
// List Of Users Component:
import React, { useState, useEffect } from "react";
import Loading from "./Loading";
import SignUpForm from "./SignUpForm";
import "./User.css";
const User = () => {
const [userList, setUserList] = useState([]);
const [loading, setLoading] = useState(true);
const [isFormVisible, setIsFormVisible] = useState(false);
const getUsers = async () => {
setLoading(true);
try {
const response = await fetch(
"http://www.someapi.com"
);
const data = await response.json();
setUserList(data);
setLoading(false);
} catch (error) {
console.error(error.message);
setLoading(false);
}
};
useEffect(() => {
getUsers();
}, []);
if (loading) return <Loading />;
return (
<section className="section-user">
<h1>List of Users</h1>
<div className="users-table-container">
<table className="users-table">
<thead>
<tr>
<th>Username</th>
<th>User type</th>
</tr>
</thead>
<tbody>
{userList.map(({ username, userType, hashedPswd }) => (
<tr key={hashedPswd}>
<td>{username}</td>
<td>{userType}</td>
</tr>
))}
</tbody>
</table>
</div>
<button className="add-user-btn" onClick={() => setIsFormVisible(true)}>
Add User
</button>
{isFormVisible && (
<SignUpForm
isFormVisible={isFormVisible}
setIsFormVisible={setIsFormVisible}
userList={userList}
getUsers={getUsers}
/>
)}
</section>
);
};
export default User;

You are directly manipulating a state rather than using setState. In this case react does not re-render the page even if you manipulate the state. So:
// wrong
const getUsernameList = () =>
userList.forEach(({ username }) => usernameList.push(username));
// correct
const getUsernameList = () => {
const list = userList.map(user => user.username)
setUsernameList(list)
}
*Edit: I think you are not saving your response data after creating a new user

In User component add
useEffect(() => {
if (isFormVisible) getUsers();
}, [isFormVisible]);

Related

Error in console: Functions are not valid as a React child

I keep on getting this error when trying to update a product in my project:
react_devtools_backend.js:4012 Warning: Functions are not valid as a React child. This may happen if you return a Component instead of from render. Or maybe you meant to call this function rather than return it.
Index.js:
import React from 'react';
import { Provider } from 'react-redux';
import ReactDOM from 'react-dom';
import './index.css';
import App from './App';
import * as serviceWorker from './serviceWorker';
import store from './store';
ReactDOM.render(
<Provider store={store}>
<React.StrictMode>
<App />
</React.StrictMode>
</Provider>,
document.getElementById('root')
);
serviceWorker.unregister();
ProductList:
import React, { useEffect } from 'react';
import { useDispatch, useSelector } from 'react-redux';
import { Link, useParams, useNavigate, useLocation } from 'react-router-dom';
import {
createProduct,
deleteProduct,
listProducts,
} from '../actions/productActions';
import LoadingBox from '../components/LoadingBox';
import MessageBox from '../components/MessageBox';
import {
PRODUCT_CREATE_RESET,
PRODUCT_DELETE_RESET,
} from '../constants/productConstants';
export default function ProductListScreen(props) {
const navigate = useNavigate();
const { pageNumber = 1 } = useParams();
const { pathname } = useLocation();
const sellerMode = pathname.indexOf('/seller') >= 0;
const productList = useSelector((state) => state.productList);
const { loading, error, products, page, pages } = productList;
const productCreate = useSelector((state) => state.productCreate);
const {
loading: loadingCreate,
error: errorCreate,
success: successCreate,
product: createdProduct,
} = productCreate;
const productDelete = useSelector((state) => state.productDelete);
const {
loading: loadingDelete,
error: errorDelete,
success: successDelete,
} = productDelete;
const userSignin = useSelector((state) => state.userSignin);
const { userInfo } = userSignin;
const dispatch = useDispatch();
useEffect(() => {
if (successCreate) {
dispatch({ type: PRODUCT_CREATE_RESET });
navigate(`/product/${createdProduct._id}/edit`);
}
if (successDelete) {
dispatch({ type: PRODUCT_DELETE_RESET });
}
dispatch(
listProducts({ seller: sellerMode ? userInfo._id : '', pageNumber })
);
}, [
createdProduct,
dispatch,
navigate,
sellerMode,
successCreate,
successDelete,
userInfo._id,
pageNumber,
]);
const deleteHandler = (product) => {
if (window.confirm('Are you sure to delete?')) {
dispatch(deleteProduct(product._id));
}
};
const createHandler = () => {
dispatch(createProduct());
};
return (
<div>
<div className="row">
<h1>Products</h1>
<button type="button" className="primary" onClick={createHandler}>
Create Product
</button>
</div>
{loadingDelete && <LoadingBox></LoadingBox>}
{errorDelete && <MessageBox variant="danger">{errorDelete}</MessageBox>}
{loadingCreate && <LoadingBox></LoadingBox>}
{errorCreate && <MessageBox variant="danger">{errorCreate}</MessageBox>}
{loading ? (
<LoadingBox></LoadingBox>
) : error ? (
<MessageBox variant="danger">{error}</MessageBox>
) : (
<>
<table className="table">
<thead>
<tr>
<th>ID</th>
<th>NAME</th>
<th>PRICE</th>
<th>CATEGORY</th>
<th>BRAND</th>
<th>ACTIONS</th>
</tr>
</thead>
<tbody>
{products.map((product) => (
<tr key={product._id}>
<td>{product._id}</td>
<td>{product.name}</td>
<td>{product.price}</td>
<td>{product.category}</td>
<td>{product.brand}</td>
<td>
<button
type="button"
className="small"
onClick={() => navigate(`/product/${product._id}/edit`)}
>
Edit
</button>
<button
type="button"
className="small"
onClick={() => deleteHandler(product)}
>
Delete
</button>
</td>
</tr>
))}
</tbody>
</table>
<div className="row center pagination">
{[...Array(pages).keys()].map((x) => (
<Link
className={x + 1 === page ? 'active' : ''}
key={x + 1}
to={`/productlist/pageNumber/${x + 1}`}
>
{x + 1}
</Link>
))}
</div>
</>
)}
</div>
);
}
Product Edit Page:
import React, { useEffect, useState } from 'react';
import { useDispatch, useSelector } from 'react-redux';
import Axios from 'axios';
import { useNavigate, useParams } from 'react-router-dom';
import { detailsProduct, updateProduct } from '../actions/productActions';
import LoadingBox from '../components/LoadingBox';
import MessageBox from '../components/MessageBox';
import { PRODUCT_UPDATE_RESET } from '../constants/productConstants';
export default function ProductEditScreen(props) {
const navigate = useNavigate();
const params = useParams();
const { id: productId } = params;
const [name, setName] = useState('');
const [price, setPrice] = useState('');
const [image, setImage] = useState('');
const [category, setCategory] = useState('');
const [countInStock, setCountInStock] = useState('');
const [brand, setBrand] = useState('');
const [description, setDescription] = useState('');
const productDetails = useSelector((state) => state.productDetails);
const { loading, error, product } = productDetails;
const productUpdate = useSelector((state) => state.productUpdate);
const {
loading: loadingUpdate,
error: errorUpdate,
success: successUpdate,
} = productUpdate;
const dispatch = useDispatch();
useEffect(() => {
if (successUpdate) {
navigate('/productlist');
}
if (!product || product._id !== productId || successUpdate) {
dispatch({ type: PRODUCT_UPDATE_RESET });
dispatch(detailsProduct(productId));
} else {
setName(product.name);
setPrice(product.price);
setImage(product.image);
setCategory(product.category);
setCountInStock(product.countInStock);
setBrand(product.brand);
setDescription(product.description);
}
}, [product, dispatch, productId, successUpdate, navigate]);
const submitHandler = (e) => {
e.preventDefault();
// TODO: dispatch update product
dispatch(
updateProduct({
_id: productId,
name,
price,
image,
category,
brand,
countInStock,
description,
})
);
};
const [loadingUpload, setLoadingUpload] = useState(false);
const [errorUpload, setErrorUpload] = useState('');
const userSignin = useSelector((state) => state.userSignin);
const { userInfo } = userSignin;
const uploadFileHandler = async (e) => {
const file = e.target.files[0];
const bodyFormData = new FormData();
bodyFormData.append('image', file);
setLoadingUpload(true);
try {
const { data } = await Axios.post('/api/uploads', bodyFormData, {
headers: {
'Content-Type': 'multipart/form-data',
Authorization: `Bearer ${userInfo.token}`,
},
});
setImage(data);
setLoadingUpload(false);
} catch (error) {
setErrorUpload(error.message);
setLoadingUpload(false);
}
};
return (
<div>
<form className="form" onSubmit={submitHandler}>
<div>
<h1>Edit Product {productId}</h1>
</div>
{loadingUpdate && <LoadingBox></LoadingBox>}
{errorUpdate && <MessageBox variant="danger">{errorUpdate}</MessageBox>}
{loading ? (
<LoadingBox></LoadingBox>
) : error ? (
<MessageBox variant="danger">{error}</MessageBox>
) : (
<>
<div>
<label htmlFor="name">Name</label>
<input
id="name"
type="text"
placeholder="Enter name"
value={name}
onChange={(e) => setName(e.target.value)}
></input>
</div>
<div>
<label htmlFor="price">Price</label>
<input
id="price"
type="text"
placeholder="Enter price"
value={price}
onChange={(e) => setPrice(e.target.value)}
></input>
</div>
<div>
<label htmlFor="image">Image</label>
<input
id="image"
type="text"
placeholder="Enter image"
value={image}
onChange={(e) => setImage(e.target.value)}
></input>
</div>
<div>
<label htmlFor="imageFile">Image File</label>
<input
type="file"
id="imageFile"
label="Choose Image"
onChange={uploadFileHandler}
></input>
{loadingUpload && <LoadingBox></LoadingBox>}
{errorUpload && (
<MessageBox variant="danger">{errorUpload}</MessageBox>
)}
</div>
<div>
<label htmlFor="category">Category</label>
<input
id="category"
type="text"
placeholder="Enter category"
value={category}
onChange={(e) => setCategory(e.target.value)}
></input>
</div>
<div>
<label htmlFor="brand">Brand</label>
<input
id="brand"
type="text"
placeholder="Enter brand"
value={brand}
onChange={(e) => setBrand(e.target.value)}
></input>
</div>
<div>
<label htmlFor="countInStock">Count In Stock</label>
<input
id="countInStock"
type="text"
placeholder="Enter countInStock"
value={countInStock}
onChange={(e) => setCountInStock(e.target.value)}
></input>
</div>
<div>
<label htmlFor="description">Description</label>
<textarea
id="description"
rows="3"
type="text"
placeholder="Enter description"
value={description}
onChange={(e) => setDescription(e.target.value)}
></textarea>
</div>
<div>
<label></label>
<button className="primary" type="submit">
Update
</button>
</div>
</>
)}
</form>
</div>
);
}
what could be the problem?
The code should redirect me to a new page in which i can create a new product and add it to my database

POST http://localhost:7500/api/users/posts 400 (Bad Request)

So I am trying to save some data into a mongodb data base using axios
I created a form to fill then when i click on save the data must be saved.
this is my try:
import auction1 from '../../Images/auction1.png'
import {useState} from 'react';
import './HomeScreen.css'
import {Button, Modal } from 'react-bootstrap';
import axios from 'axios';
const HomeScreen = ()=>{
const [show, setShow] = useState(false);
const handleClose = () => setShow(false);
const handleShow = () => setShow(true);
const [name, setName] = useState("");
const [price, setPrice] = useState(null);
const [deadline, setDeadLine] = useState("");
const [description, setDescription] = useState("");
const [img, setImg] = useState("");
const [imgMessage, setImgMessage] = useState(null);
const [error, setError] = useState(false);
const handleSubmit = async(e)=>{
e.preventDefault();
try{
const config = {
headers: {
"Content-Type": "application/json",
}
}
const {data} = await axios.post("http://localhost:7500/api/users/posts",
{name, img, deadline, price, description},
config
);
console.log(data);
}catch(error){
console.log(error.response.data.message);
}
};
const postDetails = (pic)=>{
if(!pic){
return setImgMessage('Please select a picture');
}
setImgMessage(null);
if(pic.type === 'images/jpeg' || pic.type==='image/png'){
const data = new FormData();
data.append('file', pic);
data.append('upload_preset', 'battta');
data.append('cloud_name', 'ChkounZed');
fetch("https://api.cloudinary.com/v1_1/ChkounZed/upload", {
method: 'post',
body: data
})
.then((res)=> res.json())
.then((data)=> {
console.log(data);
setImg(data.url.toString())
})
.catch((error)=>{
console.log(error);
});
}else{
return setImgMessage('Please select a picture');
}
};
return(
<div className="container bg">
<img src ={auction1} className='landing-image' />
<div style={{marginLeft:460}}>
<Button variant="primary" onClick={handleShow}>
Create Post
</Button>
</div>
<Modal show={show} onHide={handleClose}>
<form onSubmit={handleSubmit}>
<Modal.Header closeButton>
<Modal.Title>Create Post</Modal.Title>
</Modal.Header>
<Modal.Body>
<form >
<div className="form-group">
<label>Post Name:</label>
<input type="text" className="form-control" placeholder="Enter Name"
value={name} onChange={(e)=> setName(e.target.value)}/>
</div>
<div className="form-group">
<label>Post Images:</label>
<input type="file" className="form-control" multiple onChange="readURL(this)" accept="Image/*"
onChange={(e)=> postDetails(e.target.files[0])}/>
</div>
<div>
<label>Price:</label>
<input type="number" className="form-control" placeholder="TND"
value={price} onChange={(e)=> setPrice(e.target.value)}/>
</div>
<div>
<label>DeadLine:</label>
<input type="datetime-local" className="form-control"
value={deadline} onChange={(e)=> setDeadLine(e.target.value)}/>
</div>
<div>
<label>Description:</label>
<textarea className="form-control" rows="3"
value={description} onChange={(e)=> setDescription(e.target.value)}/>
</div>
</form>
</Modal.Body>
<Modal.Footer>
<button type="submit" className="btn btn-primary" data-bs-dismiss="modal" onClick={handleClose} >
Save Post
</button>
<button type="submit" className="btn btn-secondary" data-bs-dismiss="modal" onClick={handleClose}>
Close
</button>
</Modal.Footer>
</form>
</Modal>
</div>
)
};
export default HomeScreen;
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.6.3/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.6.3/umd/react-dom.production.min.js"></script>
that was my react component and the problem is that i keep getting a message that says the post already exists.
this is my postController from the backend side:
const Post = require("../Models/postModel");
const asyncHandler = require("express-async-handler");
const savePost = asyncHandler(async(req,res)=>{
const {name, deadline, price, description, image} = req.body;
const postExists = await Post.findOne({image});
if(postExists){
res.status(400);
throw new Error('Post Already Exists');
}
const post = await Post.create({
name,
deadline,
price,
description,
image
});
if(post){
res.status(201).json({
_id: post._id,
name: post.name,
price: post.price,
image: post.image,
deadline: post.deadline,
description: post.description
});
}else{
res.status(400);
throw new Error('Error');
}
});
module.exports = {savePost};
I would be so grateful if you can give me hand of this and by the way i wanna make my post unique using the images and still did not know how
Can you provide more information? Your Post Model. What happens at the DB Collection? Is it empty?
The response of mongodb includes _id why not use findById instead of find({image}).
When u wipe your database and post the first time whats the response of your post to /api/users/posts?
To make some fields unique for the collection you can use unique like below:
const PlayerSchema = new mongoose.Schema({
name:{
type: String,
unique: true
}
})

react js and node Can't see img of new user

When I try to register a new user all data are passed except "avatar", even if that avatar is regularly uploaded on my Cloudinary.
Don't even know what is the problem in and tried to find answer on google but unsuccessfully, so any help is very welcome :D
Here is some code, if need more tell me in a comment and I'll send you
Cannot finish my site, don't know what to do...
// frontend Register component
import React, { Fragment, useState, useEffect } from 'react';
import { useNavigate } from 'react-router-dom';
import MetaData from '../layout/MetaData';
import { useAlert } from 'react-alert';
import { useDispatch, useSelector } from 'react-redux';
import { register, clearErrors } from '../../actions/userActions';
const Register = () => {
const navigate = useNavigate();
const [user, setUser] = useState({
name: '',
email: '',
password: '',
});
const { name, email, password } = user;
const [avatar, setAvatar] = useState('');
const [avatarPreview, setAvatarPreview] = useState(
'/images/default_avatar.jpg'
);
const alert = useAlert();
const dispatch = useDispatch();
const { isAuthenticated, error, loading } = useSelector(
(state) => state.auth
);
useEffect(() => {
if (isAuthenticated) {
navigate('/');
}
if (error) {
alert.error(error);
dispatch(clearErrors());
}
}, [dispatch, alert, isAuthenticated, error, navigate]);
const submitHandler = (e) => {
e.preventDefault();
const formData = new FormData();
formData.set('name', name);
formData.set('email', email);
formData.set('password', password);
formData.set('avatar', avatar);
dispatch(register(formData));
};
const onChange = (e) => {
if (e.target.name === 'avatar') {
const reader = new FileReader();
reader.onload = () => {
if (reader.readyState === 2) {
setAvatarPreview(reader.result);
setAvatar(reader.result);
}
};
reader.readAsDataURL(e.target.files[0]);
} else {
setUser({ ...user, [e.target.name]: e.target.value });
}
};
return (
<Fragment>
<MetaData title={'Register User'} />
<div className='row wrapper'>
<div className='col-10 col-lg-5'>
<form
className='shadow-lg'
onSubmit={submitHandler}
encType='multipart/form-data'
>
<h1 className='mb-3'>Register</h1>
<div className='form-group'>
<label htmlFor='email_field'>Name</label>
<input
type='name'
id='name_field'
className='form-control'
name='name'
value={name}
onChange={onChange}
/>
</div>
<div className='form-group'>
<label htmlFor='email_field'>Email</label>
<input
type='email'
id='email_field'
className='form-control'
name='email'
value={email}
onChange={onChange}
/>
</div>
<div className='form-group'>
<label htmlFor='password_field'>Password</label>
<input
type='password'
id='password_field'
className='form-control'
name='password'
value={password}
onChange={onChange}
/>
</div>
<div className='form-group'>
<label htmlFor='avatar_upload'>Avatar</label>
<div className='d-flex align-items-center'>
<div>
<figure className='avatar mr-3 item-rtl'>
<img
src={avatarPreview}
className='rounded-circle'
alt='Avatar Preview'
/>
</figure>
</div>
<div className='custom-file'>
<input
type='file'
name='avatar'
className='custom-file-input'
id='customFile'
accept='iamges/*'
onChange={onChange}
/>
<label className='custom-file-label' htmlFor='customFile'>
Choose Avatar
</label>
</div>
</div>
</div>
<button
id='register_button'
type='submit'
className='btn btn-block py-3'
disabled={loading ? true : false}
>
REGISTER
</button>
</form>
</div>
</div>
</Fragment>
);
};
export default Register;
// backend Register a user => /api/v1/register
exports.registerUser = catchAsyncErrors(async (req, res, next) => {
const result = await cloudinary.v2.uploader.upload(req.body.avatar, {
folder: 'avatars',
width: 150,
crop: 'scale',
});
const { name, email, password } = req.body;
const user = await User.create({
name,
email,
password,
avatar: {
public_id: result.public_id,
url: result.secure_url,
},
});
sendToken(user, 200, res);
});

how to check if the fetch variable has data

function Login() {
const [email, setEmail] = useState("");
const [password, setpassword] = useState("");
const [users, setUser] = useState([]);
function login() {
fetch(
"http://116.202.231.219:8069/Restaurant/Login_Updated?Cont4=" +
email +
"&Pswd=" +
password
).then((result) => {
result.json().then((resp) => {
// console.warn(resp)
setUser(resp);
console.log(resp);
});
});
}
return (
<div className="col-sm-6 offset-sm-3">
<h1>Login Page</h1>
<br />
<input
type="text"
className="form-control"
onChange={(e) => setEmail(e.target.value)}
/>
<br />
<br />
<input
type="password"
className="form-control"
onChange={(e) => setpassword(e.target.value)}
/>
<br />
<br />
<button onClick={login} className="btn btn-primary">
Login
</button>
</div>
);
}
now I want to check that if the data being fetched is the same as the data being put in the inputs so I am trying using "IF" but the "RESP" variable is not global I mean that it is not working with "IF". So can you guys help me how to do a check that the Email pass is equal to the Email pass from the API.
As you can see that API is getting the cont4 and pass from the input tags and giving back the objects in return but I am not able to run the success check on this API that if it returns object go to dashboard else throw alert of error
import axios from 'axios';
//add axios in your project
function Login() {
const [email, setEmail] = useState("");
const [password, setpassword] = useState("");
const [users, setUser] = useState({});
loginHandel = () => {
const url = `http://116.202.231.219:8069/Restaurant/Login_Updated?Cont4=${email}&Pswd=${password}`
axios.get(url).then((res) => {
//check the res if its getting the correct data or not?
//restructure accordingly
console.log(res);
const persons = res;
if ((persons?.email === email) && (persons?.password === password)) {
//perform any thing here
setUser(persons);
} else {
console.log("User email and passwoed mismatched!")
}
}).catch(err => {
//handel your error
console.log(err);
})
}
return (
<div className="col-sm-6 offset-sm-3">
<h1>Login Page</h1>
<br />
<form>
</form>
<input
type="text"
className="form-control"
onChange={(e) => setEmail(e.target.value)}
/>
<br />
<br />
<input
type="password"
className="form-control"
onChange={(e) => setpassword(e.target.value)}
/>
<br />
<br />
<button onClick={loginHandel} className="btn btn-primary">
Login
</button>
</div>
);
}

ReactJs how to scroll to bottom of div on click or submit

I want to scroll to the bottom of the div whenever a new message is sent in the Message. I can do this with jQuery but wondering what the best approach in React is.
This is the Messages.js component I am in. Thank you in advance!
const Messages = (props) => {
const [inputMessage, setInputMessage] = useState('');
const handleChange = (event) => {
setInputMessage(event.target.value);
}
const handleSubmit = (event, message) => {
event.preventDefault();
props.setRoomMessages([...props.roomMessages, {id: Date.now(), name: props.username, message: inputMessage}]);
setInputMessage('');
}
const messages = props.roomMessages.map((message, index) => {
return (
<Message
key={index}
name={message?.name}
message={message?.message}
/>
)
})
return (
<>
<div className="Messages">
{messages}
</div>
<form className="chat-input form-inline" onSubmit={handleSubmit}>
<div className="form-group">
<input
className="form-control"
type="text"
value={inputMessage}
placeholder="Type a message..."
onChange={handleChange}
/>‍
<button className="btn btn-link">Send</button>
</div>
</form>
</>
)
}
export default Messages;
Try this, one way to do it is to use ref
import { useState, useRef } from 'react';
const Messages = props => {
const [inputMessage, setInputMessage] = useState('');
const myMessage = useRef(null);
const handleChange = event => {
setInputMessage(event.target.value);
};
const handleSubmit = (event, message) => {
event.preventDefault();
props.setRoomMessages([...props.roomMessages, { id: Date.now(), name: props.username, message: inputMessage }]);
setInputMessage('');
// HERE IS THE NEW CODE
if (myMessage && myMessage.current) {
myMessage.current.scrollTop = myMessage.current.scrollHeight;
}
};
const messages = props.roomMessages.map((message, index) => {
return <Message key={index} name={message?.name} message={message?.message} />;
});
return (
<>
<div className="Messages" ref={myMessage}>
{messages}
</div>
<form className="chat-input form-inline" onSubmit={handleSubmit}>
<div className="form-group">
<input
className="form-control"
type="text"
value={inputMessage}
placeholder="Type a message..."
onChange={handleChange}
/>
‍<button className="btn btn-link">Send</button>
</div>
</form>
</>
);
};
export default Messages;

Categories