react ternary operator problem, solvable only with jquery? - javascript

I'm new to React and try to make a simple crud with Springboot.
at certain point I need to use a ternary operator, but it doesn't work. I used it before in React with no problem, I don't understand why now is not working.
So I used a function and is working, except when I have to empty a div, which gave me a problem and need to use jquery. So now the code is working, I just would like to know what I'm doing wrong in the ternary and in emptying the div with javascript.
I will post the full working code, then just the piece of code that would like to use vs the code that is actually working.
Thanks for your patience
import { React, useState, useEffect } from "react";
import { useHistory } from "react-router";
import ServiceUtente from "../service/ServiceUtente";
import $ from "jquery";
const Utente = () => {
const history = useHistory();
const [utenti, setUtenti] = useState([]);
const [isDeleted, setIsDeleted] = useState(false);
const [searchBy, setSearchBy] = useState("");
let checkedNome = false;
let checkedEmail = false;
let checkedProfilo = false;
useEffect(() => {
retrieveUtenti();
}, [isDeleted]);
// retrieve data from db and store it into utenti
const retrieveUtenti = () => {
ServiceUtente.utenteGetAll()
.then((response) => {
setUtenti(response.data);
})
.catch((e) => {
console.log(e);
});
};
const viewUtente = (id) => {
history.push(`/view-utente/${id}`);
};
const aggiungiUtente = () => {
history.push("/aggiungi-update-utente/_add");
};
const deleteUtente = (id) => {
ServiceUtente.utenteDelete(id)
.then((response) => {
setIsDeleted(!isDeleted);
})
.catch((e) => {
console.log(e);
});
};
const updateUtente = (id) => {
history.push(`/aggiungi-update-utente/${id}`);
};
const handleSearch = (e) => {
setSearchBy(e.target.value);
};
const handleNome = (e) => {
checkedNome = e.target.checked;
console.log("nome: " + checkedNome);
nomeForm();
};
const handleEmail = (e) => {
checkedEmail = e.target.checked;
console.log("email: " + checkedEmail);
};
const handleProfilo = (e) => {
checkedProfilo = e.target.checked;
console.log("profilo: " + checkedProfilo);
};
const formSearchBy = () => {
// console.log("");
};
const nomeForm = () => {
if (checkedNome === true) {
document.getElementById("nomeForm").innerHTML = `
<input
type="text"
className="form-control"
placeholder="Search Utente"
value="${searchBy}"
onChange="${handleSearch}"
/>`;
} else {
// document.getElementById("nomeForm").innerHTML = "";
$("#nomeForm").empty();
}
};
return (
<div className="row">
<div className="col-sm-10 offset-1">
<h2 className="login-title my-4" style={{ textAlign: "center" }}>
GM Utente
</h2>
{/* ***********************SEARCH BAR****************************************** */}
<form onClick={formSearchBy}>
<h4 style={{ textAlign: "center" }}>
Spuntare i campi desiderati per la ricerca
</h4>
<div className="form-check">
<input
onChange={handleNome}
className="form-check-input"
type="checkbox"
name="nomeCheck"
value=""
id="nomeUtente"
/>
<label className="form-check-label" htmlFor="nomeUtente">
Nome Utente
</label>
<div id="nomeForm">{nomeForm()}</div>
</div>
<div
className="input-group-append my-2 text-center"
style={{ textAlign: "center" }}
>
<button
className="btn btn-success"
type="submit"
id="button-addon2"
>
Search
</button>
</div>
</form>
{/* ***********************END SEARCH BAR*********************************** */}
<button
type="button"
className="btn btn-primary my-2"
onClick={() => aggiungiUtente()}
>
Aggiungi Utente
</button>
<table
className="table table-striped table-bordered"
style={{ textAlign: "center" }}
>
<thead>
<tr>
<th>Id Utente</th>
<th>Nome Utente</th>
<th>Email</th>
<th>Password</th>
<th>Profilo Utente</th>
<th>Azioni</th>
</tr>
</thead>
<tbody>
{utenti.map((utente) => (
<tr key={utente.idUtente}>
<td>{utente.idUtente}</td>
<td>{utente.nomeUtente}</td>
<td>{utente.email}</td>
<td>{utente.password}</td>
<td>{utente.profiloUtente.nomeProfilo}</td>
<td>
<button
onClick={() => viewUtente(utente.idUtente)}
type="button"
className="btn btn-secondary mx-1"
>
Details
</button>
<button
onClick={() => updateUtente(utente.idUtente)}
type="button"
className="btn btn-warning mx-1"
>
Update
</button>
<button
onClick={() => deleteUtente(utente.idUtente)}
type="button"
className="btn btn-danger mx-1"
>
Delete
</button>
</td>
</tr>
))}
</tbody>
</table>
</div>
</div>
);
};
export default Utente;
All this code is working but I would like to use this
{checkedNome === true ? (
<input
type="text"
className="form-control"
placeholder="Search Utente"
value={searchBy}
onChange={handleSearch}
/>
) : null}
Instead of this function
const nomeForm = () => {
if (checkedNome === true) {
document.getElementById("nomeForm").innerHTML = `
<input
type="text"
className="form-control"
placeholder="Search Utente"
value="${searchBy}"
onChange="${handleSearch}"
/>`;
} else {
// document.getElementById("nomeForm").innerHTML = "";
$("#nomeForm").empty();
}
};
Also, in this function, why the Jquery syntax is working and the '.innerHTML = "";' commented out is not?
Thanks

Issue
The issue is that you aren't updating any state in order to trigger a render. checkedNome is declared in the function body and mutating it won't trigger React to do anything.
let checkedNome = false;
const handleNome = (e) => {
checkedNome = e.target.checked; // <-- mutation
console.log("nome: " + checkedNome);
nomeForm(); // <-- DOM mutation
};
Solution
Move the checkedNome into component state:
const [checkedNome, setCheckedNome] = React.useState(false);
Update handleNome to enqueue a state update:
const handleNome = (e) => {
const { checked } = e.target;
setCheckedNome(checked);
};
Update the render return to conditionally render the input:
<div id="nomeForm">
{checkedNome && (
<input
type="text"
className="form-control"
placeholder="Search Utente"
value={searchBy}
onChange={handleSearch}
/>
)}
</div>

Related

onSubmit() form is not working or triggered

I'm trying to implement a function that will accept an attribute called customer_name to create a new customer. Here is my code:
import { connect } from 'react-redux'
import React, { useState, useEffect } from 'react'
import { createCustomer, initialCreate } from '../../redux'
const CreateCustomer = ( { createCustomer, initialCreate, userData } ) => {
const returnNull = () => {
return null
}
const [actionType, setActionType] = useState('')
const [formData, setFormData] = useState({
customer_name: ''
});
const { customer_name } = formData;
const [effectRan, setEffectRan] = useState(false)
const onChange = e => setFormData({
...formData,
[e.target.name]: e.target.value
})
useEffect(() => {
if(!effectRan) {
setEffectRan(true)
initialCreate()
}
}, [effectRan])
const onClick = e => {
e.preventDefault()
setActionType(e.target.name)
console.log(actionType)
};
const onSubmit = e => {
console.log('first')
console.log(actionType);
e.preventDefault();
actionType === 'create' ? createCustomer(customer_name) : returnNull();
initialCreate();
}
return userData ? (
<div>
<form onSubmit={e => onSubmit(e)}>
<table className="table">
<thead>
<tr>
<th scope="col">Customer Name</th>
<th scope="col">Action</th>
</tr>
</thead>
<tbody>
<tr>
<td>
<input
placeholder=''
className='form-control'
id="InputCustomerName"
name="customer_name"
value={customer_name}
onChange={e => onChange(e)}
>
</input>
</td>
<td>
<button
type="submit"
name="create"
className="btn btn-primary"
onClick={e => onClick(e)}
>Create
</button>
</td>
</tr>
</tbody>
</table>
</form>
</div>
) : (
<div className="text-center">
<div className="spinner-border" role="status">
<span className="sr-only">Loading...</span>
</div>
</div>
)
};
const mapStateToProps = state => ({
// is authenticated?
isAuthenticated: state.auth.isAuthenticated,
userData: state.customer.customer,
createSuccess: state.customer.createSuccess
})
const mapDispatchToProps = dispatch => {
return {
createCustomer: (customer_name) => dispatch(createCustomer(customer_name)),
initialCreate: () => dispatch(initialCreate())
}
}
export default connect(mapStateToProps, mapDispatchToProps) (CreateCustomer);
The problem is my submit button seems not working, I can't see any information in my console when I clicked the create button. While I can see the information in the onClick method which means the button is clicked.
I uncommented my code one by one, I found that I can't have two preventDefault() in both onClick and onSubmit.
So, I uncommented the preventDefault() in my onClick() function.
I'm sorry, I'm not very familiar with react.js, I need to look up some information about this preventDefault()

Accessing Values of Keydown in React

I'm a beginner creating a basic calculator app, expanding on a tutorial I followed. I'd like to add functionality to accept keyboard input in addition to the onClick events. I've tried the methods used in the docs, but it ends up duplicating the last clicked value instead of inputting the correct value. Here's my app:
import { useState } from "react"
function App() {
const [calc, setCalc] = useState("")
const [result, setResult] = useState("")
const ops = ['/', '*', '+', '-', '.']
const updateCalc = value => {
if (
(ops.includes(value) && calc === "") ||
(ops.includes(value) && ops.includes(calc.slice(-1)))
) {
setCalc(calc.slice(0,-1) + value)
return;
}
setCalc(calc + value)
if (!ops.includes(value)) {
setResult(eval(calc + value).toString());
}
}
const createDigits = () => {
const digits = []
for (let i = 1; i < 10; i++) {
digits.push(
<input type="button"
onClick={() => updateCalc(i.toString())} key={i}
onKeyPress={() => updateCalc(i.toString())}
value={i} />
)
}
return digits
}
const calculate = () => {
setCalc(eval(calc).toString())
setResult("")
}
const deleteLast = () => {
if (calc === "") {
return;
}
const value = calc.slice(0, -1);
setCalc(value)
}
return (
<div className="App">
<div className="calculator">
<div className="display">
{result ? <span>({result})</span> : ""}
{ calc || "0"}
</div>
<div className="operators">
<input type="button" onClick={() => updateCalc("/")} value="/" />
<input type="button" onClick={() => updateCalc("*")} value="*" />
<input type="button" onClick={() => updateCalc("+")} value="+" />
<input type="button" onClick={() => updateCalc("-")} value="-" />
<input type="button" onClick={deleteLast} value="DEL" />
</div>
<div className="digits">
{ createDigits() }
<input type="button" onClick={() => updateCalc("0")} value="0" />
<input type="button" onClick={() => updateCalc(".")} value="." />
<input type="button" onClick={calculate} value="=" />
</div>
</div>
</div>
);
}
export default App;
You can achieve this with the concept of useEffect and watch for the keydown event. If the key is pressed you can check the value and call updateCalc function in handleKeyPress:
// handle what happens on key press
const handleKeyPress = useCallback((event) => {
// Call updateCalc here
console.log(`Key pressed: ${event.key}`);
}, []);
useEffect(() => {
// attach the event listener
document.addEventListener('keydown', handleKeyPress);
// remove the event listener
return () => {
document.removeEventListener('keydown', handleKeyPress);
};
}, [handleKeyPress]);

BootStrap Modal is refreshed on KeyPress

I know there are question asked before, but I have tried the solution but it's not working. I have split the component differently but then also it refresh on every single keypress.
const TenementRegistration = () => {
const [show, setShow] = useState(false);
const [name, setName] = useState("");
const [editId, setEditId] = useState("");
function Example() {
const onSubmitHandler = async () => {
const data = {
name: name
}
await services.postService("User", data).then((res) => {
onGetUserData();
});
}
return(
<Modal
show={show}
onHide={() => setShow(false)}
size="lg"
aria-labelledby="example-custom-modal-styling-title"
scrollable="true"
centered
animation="true"
>
<Modal.Header closeButton>
<Modal.Title id="example-custom-modal-styling-title">
Add User
</Modal.Title>
</Modal.Header>
<Modal.Body>
<div className="form-container">
<form>
<Row>
<div className="form-group col-12 col-md-6
center">
<label for="inputName" className="asy-
FormLabel">
Name
</label>
<input
type="text"
className="form-control asy-InputValues"
id="policyName"
placeholder="Enter Property Id"
onChange={(e) => {
setName(e.target.value);
}}
value={name}
required
/>
</div>
</Row>
</form>
</div>
</Modal.Body>
<Modal.Footer>
<button
type="button"
className="submit-button"
onClick={() => {
onSubmitHandler();
}}
>
Submit
</button>
</Modal.Footer>
</Modal>
const [data, setData] = useState([]);
useEffect(() => {
onGetUserData();
}, []);
const onGetUserData = async () => {
services.getService("User").then((res) => {
setData(res.data);
});
};
const onEditData = async (id) => {
setShow(true);
const newData = data.filter((obj) => obj.id === id)[0];
setName(newData.name);
}
//Table where we show name and pass id to update button
}
I have also tried to Split the Modal and separate the form (not in this example) but it didn't work any suggestions how to handle the modal problem
Try this
In your button onClick
<button
type="button"
className="submit-button"
onClick={(event) =>
{
onSubmitHandler(event);
}}
>
Submit
</button>
then in that function:
const onSubmitHandler = async (event) => {
event.preventDefault()
const data = {
name: name
}
await services.postService("User", data).then((res) => {
onGetUserData();
});
}

All comment forms submit the same docId

I have a react app (a sort of twitter clone) that uses firestore for storing posts and comments on posts. Each post is rendered as an element from an array using array.map(). Each post has a comment button that opens a form to take in a comment and add it to the post. When I enter a comment and submit it, the topmost post is always the one commented on no matter which post contained the comment button that was clicked(docId for the most recently saved firestore document is always submitted by the comment button instead of the docId corresponding to that instance of the component).
The map of the posts (called "howls"):
<div className="timeline">
{sortedHowls &&
sortedHowls.map((howl) => (
<Howl
key={howl.id}
image={howl.image}
text={howl.text}
time={howl.time}
userId={howl.userId}
docId={howl.id}
comments={howl.comments}
likes={howl.likes}
/>
))}
</div>
The Howl Component looks like this:
import React, { useEffect, useState } from "react";
import { useSelector } from "react-redux";
import { useFirestoreConnect } from "react-redux-firebase";
import { firestore } from "../../../firebase-store";
// styles
import "./Howl.scss";
// components
import Avatar from "../Avatar/Avatar";
import { FontAwesomeIcon } from "#fortawesome/react-fontawesome";
// functions
import timeCalc from "./timeCalc";
// icons
import { faStar, faComment } from "#fortawesome/free-solid-svg-icons";
const Howl = ({ docId, userId, text, image, time, comments, likes }) => {
useFirestoreConnect([{ collection: "users" }]);
const [commenting, toggleCommenting] = useState(false);
const [newComment, setNewComment] = useState("");
const [users, setUsers] = useState(null);
const [user, setUser] = useState(null);
const getUsers = useSelector((state) => state.firestore.ordered.users);
useEffect(() => {
if (!users) {
setUsers(getUsers);
} else {
setUser(users.find((doc) => doc.uid === userId));
}
}, [users, user, userId, getUsers]);
const handleLike = () => {
const newLikesTotal = likes + 1;
firestore.collection("howls").doc(docId).update({ likes: newLikesTotal });
};
const handleComment = () => {
toggleCommenting(!commenting);
};
const handleChange = (event) => {
setNewComment(event.currentTarget.value);
};
const submitComment = (event) => {
event.preventDefault();
const { id } = event.currentTarget;
console.log(event.currentTarget);
const resetComment = () => {
toggleCommenting(!commenting);
setNewComment("");
};
if (comments) {
firestore
.collection("howls")
.doc(id)
.update({
comments: [...comments, newComment],
})
.then(() => resetComment());
} else {
firestore
.collection("howls")
.doc(id)
.update({ comments: [newComment] })
.then(() => resetComment());
}
};
return (
<div className="howl">
<div className="avatar-container">
<Avatar
photoURL={user ? user.photoURL : ""}
displayName={user ? user.displayName : ""}
/>
</div>
<div className="name-text-img-container">
<p className="userName">
{user && user.displayName} - {timeCalc(Date.now(), time)}
</p>
<p className="howl-text">{text}</p>
<div className="img-container">
{image ? (
<img src={image} alt="user uploaded" className="img" />
) : null}
</div>
<div className="buttons-container">
<form action="" className="buttons">
<label htmlFor="comment-button">
<FontAwesomeIcon icon={faComment} className="image-icon" />
</label>
<input
id="comment-button"
type="checkbox"
onClick={handleComment}
style={{ display: "none" }}
/>
<label htmlFor="like-button">
<FontAwesomeIcon icon={faStar} className="image-icon" />
</label>
<input
id="like-button"
type="checkbox"
onClick={handleLike}
style={{ display: "none" }}
/>
<label htmlFor="like-button">{likes > 0 && likes}</label>
</form>
</div>
{commenting && (
<div className="comment-form">
<form action="submit" onSubmit={submitComment} id={docId}>
<input
type="text"
name="comment-input"
className="comment-input"
maxLength={128}
onChange={handleChange}
value={newComment}
placeholder="Enter comment"
/>
<div className="buttons">
<button type="submit">Submit</button>
<button onClick={() => toggleCommenting(!commenting)}>
Cancel
</button>
</div>
</form>
</div>
)}
<div className="comments">
{comments
? comments.map((comment, index) => {
return (
<p key={index} className="comment">
{comment}
</p>
);
})
: null}
</div>
</div>
</div>
);
};
export default Howl;
How can I get the comment button to specify the correct document to update?
Link to my full repo.
It turns out that the problem is here:
<form action="" className="buttons">
<label htmlFor="comment-button">
<FontAwesomeIcon icon={faComment} className="image-icon" />
</label>
<input
id="comment-button"
type="checkbox"
onClick={handleComment}
style={{ display: "none" }}
/>
<label htmlFor="like-button">
<FontAwesomeIcon icon={faStar} className="image-icon" />
</label>
<input
id="like-button"
type="checkbox"
onClick={handleLike}
style={{ display: "none" }}
/>
<label htmlFor="like-button">{likes > 0 && likes}</label>
</form>
By using a form and inputs as the buttons instead of using <button /> elements it somehow confused react as to which instance of <Howl /> was opening the comment form and therefore which docId was sent to submitComment. Corrected <Howl /> component:
import React, { useEffect, useState } from "react";
import { useSelector } from "react-redux";
import { useFirestoreConnect } from "react-redux-firebase";
import { firestore } from "../../../firebase-store";
// components
import Avatar from "../Avatar/Avatar";
import CommentInput from "./CommentInput";
import Comment from "./Comment";
import ViewProfile from "../ViewProfile/ViewProfile";
import { FontAwesomeIcon } from "#fortawesome/react-fontawesome";
// functions
import timeCalc from "./timeCalc";
// styles
import "./Howl.scss";
// icons
import { faStar, faComment } from "#fortawesome/free-solid-svg-icons";
const Howl = ({ howl }) => {
useFirestoreConnect([{ collection: "users" }]);
const [commenting, toggleCommenting] = useState(false);
const [newComment, setNewComment] = useState("");
const [users, setUsers] = useState(null);
const [op, setOp] = useState(null);
const [showProfile, setShowProfile] = useState(false);
const { docId, userId, text, likes, comments, time, image } = howl;
const getUsers = useSelector((state) => state.firestore.ordered.users);
const currentUser = useSelector((state) => state.firebase.auth);
// establish user that posted this howl (op = original poster)
useEffect(() => {
users ? setOp(users.find((doc) => doc.uid === userId)) : setUsers(getUsers);
}, [users, op, userId, getUsers]);
const handleLike = () => {
const index = likes.indexOf(currentUser.uid);
let newLikes = [...likes];
if (index > 0) {
newLikes.splice(index, 1);
} else if (index === 0) {
if (likes.length > 1) {
newLikes.splice(index, 1);
} else {
newLikes = [];
}
} else {
newLikes = [...newLikes, currentUser.uid];
}
firestore.collection("howls").doc(docId).update({ likes: newLikes });
};
const handleChange = (event) => {
setNewComment(event.currentTarget.value);
};
const submitComment = (event) => {
event.preventDefault();
const { id } = event.currentTarget;
const { uid, photoURL } = currentUser;
const resetComment = () => {
toggleCommenting(!commenting);
setNewComment("");
};
firestore
.collection("howls")
.doc(id)
.update({
comments: [
...comments,
{ uid: uid, photoURL: photoURL, text: newComment },
],
})
.then(() => resetComment());
};
return (
<div className="howl">
<div className="avatar-container">
<button className="show-profile" onClick={() => setShowProfile(true)}>
<Avatar
photoURL={op ? op.photoURL : ""}
displayName={op ? op.displayName : ""}
/>
</button>
</div>
<div className="name-text-img-container">
<p className="userName">
{op && op.displayName} - {timeCalc(Date.now(), time)}
</p>
<p className="howl-text">{text}</p>
<div className="img-container">
{image && <img src={image} alt="user uploaded" className="img" />}
</div>
<div className="buttons-container">
<div className="buttons">
<button className="comment-button">
<FontAwesomeIcon
icon={faComment}
className="image-icon"
onClick={() => toggleCommenting(!commenting)}
/>
</button>
<button className="like-button" onClick={handleLike}>
<FontAwesomeIcon
icon={faStar}
className={
currentUser && likes.includes(currentUser.uid)
? "image-icon liked"
: "image-icon"
}
/>
</button>
<p>{likes.length > 0 && likes.length}</p>
</div>
</div>
{commenting && (
<CommentInput
submitComment={submitComment}
docId={docId}
toggleCommenting={toggleCommenting}
commenting={commenting}
handleChange={handleChange}
newComment={newComment}
/>
)}
{showProfile && (
<ViewProfile
user={op}
close={() => setShowProfile(false)}
update={false}
/>
)}
<div className="comments">
{comments &&
comments.map((comment, index) => {
return <Comment key={`comment${index}`} comment={comment} />;
})}
</div>
</div>
</div>
);
};
export default Howl;

Update List of users Table after POST fetch request

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]);

Categories