Why updating one field updates all the fields

Viewed 36

I'm trying to update one field for example username, when I update it updates the email with it and gives an empty string in the database! I'm using defaultValue in the inputs

(Edit Profile Page)

            <input type="text"
            className="loginInput"
            style={{ border: error ? '1px solid red' : '' }}
            defaultValue={user.username}
            onChange={(e) => setUsername(e.target.value)}/>

handleSubmit function:

const [file, setFile] = useState(null);
const [username, setUsername] = useState("");
const [email, setEmail] = useState("");
const { user, dispatch, isFetching } = useContext(Context);

const handleSubmit = async (e) => {
    e.preventDefault();
    dispatch({type: "UPDATE_START"})
    const updatedUser = {
      userId: user._id,
      username,
      email,
    };
    try {
      const res = await axios.put("/users/"+user._id, updatedUser);
      setSuccess(true);
      dispatch({ type: "UPDATE_SUCCESS", payload: res.data });
    } catch (err) {
      dispatch({type: "UPDATE_FAILURE"});
    }
  };

Back-end Configuration:

//UPDATE
router.put("/:id", async (req, res) => {
    if (req.body.userId === req.params.id) {
      if (req.body.password) {
        const salt = await bcrypt.genSalt(10);
        req.body.password = await bcrypt.hash(req.body.password, salt);
      }
      try {
        const updatedUser = await User.findByIdAndUpdate(
          req.params.id,
          {
            $set: req.body,
          },
          { new: true }
        );
        res.status(200).json(updatedUser);
      } catch (err) {
        res.status(500).json(err);
      }
    } else {
      res.status(401).json("You can update only your account!");
    }
  });

Already the inputs has username or email fetched from the back-end defaultValue={user.username}, it should show them as a placeholder, now the issue is when I edit the value of the input and leave the other one it updates the two inputs, one to the edited one and the other one returns it empty (to the front-end & back-end) as I didn't change it, I think the problem is in defaultValue , i'm not sure if i'm using the correct one.

the question is how to update one input and leave the other one the same, with no changes?

2 Answers

Have you tried with value instead of defaultValue?

Let as know.

So, after searching and looking for an answer, I figured that I'm sending an empty string for the email and the username back to the api

const [username, setUsername] = useState("");
const [email, setEmail] = useState("");

So I changed to set it like:

const [credentials, setCredentials] = useState({
    userId: user._id,
    email: user.email,
    username: user.username,
  });

  const handleChange = (e) => {
    setCredentials( (prev) => ({ ...prev, [e.target.id]: e.target.value }));

const handleSubmit = async (e) => {
    e.preventDefault();
    dispatch({type: "UPDATE_START"})
    try {
      const res = await axios.put("/users/"+user._id, credentials);
      setSuccess(true);
      dispatch({ type: "UPDATE_SUCCESS", payload: res.data });
    } catch (err) {
      dispatch({type: "UPDATE_FAILURE"});
    }
  };
  };

and for the inputs:

<input type="text"
                    className="loginInput"
                    style={{ border: error ? '1px solid red' : '' }}
                    defaultValue={user.username}
                    id="username"
                    name="username"
                    onChange={handleChange}/>

<input type="text"
                    className="loginInput"
                    style={{ border: error ? '1px solid red' : '' }}
                    defaultValue={user.email}
                    id="email"
                    name="email"
                    onChange={handleChange}/>
Related