Home > Back-end >  Update List of users Table after POST fetch request
Update List of users Table after POST fetch request

Time:10-08

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{" "}
                <a href="#">Terms & Privacy</a>
              </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;

CodePudding user response:

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

CodePudding user response:

In User component add

useEffect(() => {
 if (isFormVisible) getUsers();

}, [isFormVisible]);
  • Related