1

I am getting this error while updating the isSeller option it is working for admin but not for seller.

Warning: A component is changing an uncontrolled input of type text to be controlled. Input elements should not switch from uncontrolled to controlled (or vice versa). Decide between using a controlled or uncontrolled input element for the lifetime of the component.*

Following is my code:

import React from 'react';
import { useEffect } from 'react';
import { useState } from 'react';
import { useDispatch, useSelector } from 'react-redux';
import { detailsUser } from '../actions/userActions';
import LoadingBox from '../components/LoadingBox';
import MessageBox from '../components/MessageBox';

export default function UserEditScreen(props) {
  const userId = props.match.params.id;
  const [name, setName] = useState('');
  const [email, setEmail] = useState('');
  const [isSeller, setIsSeller] = useState(false);
  const [isAdmin, setIsAdmin] = useState(false);

  const userDetails = useSelector((state) => state.userDetails);
  const { loading, error, user } = userDetails;

  const dispatch = useDispatch();
  useEffect(()=>{
      if(!user){
          dispatch(detailsUser(userId));
      }
      else{
          setName(user.name);
          setEmail(user.email);
          setIsSeller(user.isSeller);
          setIsAdmin(user.isAdmin);
      }
  },[dispatch, user, userId])

  const submitHandler = (e) => {
    e.preventDefault();
  };
  return (
    <div>
      <form className="form" onSubmit={submitHandler}>
        <div>
          <h1>Edit User {name}</h1>
          {loading && <LoadingBox></LoadingBox>}
          {error && (
            <MessageBox variant="danger">{error}</MessageBox>
          )}
        </div>
        {loading ? (
          <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="email">Email</label>
              <input
                id="email"
                type="email"
                placeholder="Enter email"
                value={email}
                onChange={(e) => setEmail(e.target.value)}
              ></input>
            </div>
            <div>
              <label htmlFor="isSeller">Is Seller</label>
              <input
                id="isSeller"
                type="checkbox"
                checked={isSeller}
                onChange={(e) => setIsSeller(e.target.checked)}
              ></input>
            </div>
            <div>
              <label htmlFor="isAdmin">Is Admin</label>
              <input
                id="isAdmin"
                type="checkbox"
                checked={isAdmin}
                onChange={(e) => setIsAdmin(e.target.checked)}
              ></input>
            </div>
            <div>
              <button type="submit" className="primary">
                Update
              </button>
            </div>
          </>
        )}
      </form>
    </div>
  );
}
James Z
  • 12,209
  • 10
  • 24
  • 44
  • Runnable code snippets is currently supported only for `HTML, CSS, JavaScript`. You can use [Codesandbox](https://codesandbox.io/) for sharing code for other frameworks – Madhan S Mar 16 '22 at 08:03

2 Answers2

1

This warning comes when your value changes from an undefined to defined value or vice-versa.

For. e.g.

import React, {useState} from 'react'


const MyComponent = () => {
  const [email, setEmail] = useState() // Look, the value of email will be undefined in the begining
  
  return (
    <input type="text" value={email}
      {/* You can put value={email || ''} or value={isSeller || false} to fix this, so that the value passed to input is always defined or otherwise you need to make sure that the state value is never undefined */}
    onChange={(e) => setEmail(e.target.value)} 
    />
  )
}

export default MyComponent;
<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>

In your case, your input values depend on name, email, isSeller, and isAdmin. Ofcourse those values are defined in the beginning, but you have a useEffect, where you are updating the value to user.name etc. I believe in this useEffect, your states value gets undefined, because your user is undefined initially.

PS. This is only a warning, you can ignore it. Or just make sure that the value passed to input field is always defined or that it doesn't transition from undefined -> defined (i.e. uncontrolled -> controlled)

Dharman
  • 30,962
  • 25
  • 85
  • 135
Aakash Sharma
  • 79
  • 1
  • 9
0

This could be most probably because you might be getting undefined in your response of user.isSeller as explained here https://stackoverflow.com/a/47012342/10212656.

Or you can simply add !! in checked value obj of checkbox to solve this.

KvS
  • 72
  • 4