0

I want to update state with data from another page. After trying to update state I'm getting error:

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

How to properly update state using hooks ??

const [data, changeData] = useState({
    name: '',
    email: '',
    phone: '',
    cv: '',
    documents: '',
    rodo: false,
    regulations: false,
  });

  useEffect(() => {
    if (location.data) {
      changeData((prevState) => {
        return { data: { name: location.data.name } };
      });
    }
  }, []);

Input

<div className='form-control'>
                <label htmlFor='name'>
                  <i className='fas fa-user'></i>
                </label>
                <input
                  value={data.name}
                  id='name'
                  name='name'
                  onKeyPress={handleKeyPress}
                  onChange={(e) => handleChangeData(e, 'name')}
                  type='text'
                  placeholder='Imię i nazwisko'
                />
              </div>
Freestyle09
  • 4,894
  • 8
  • 52
  • 83

1 Answers1

3

Side-effect of coming from Class based component. What you were trying to do in your code is replace entire previous state stored in data with new object that looked like below:

{ data: { name: location.data.name } }

In Hooks world you define individual item to have individual useState but to continue on what you are working on here's the fix:

const [data, changeData] = useState({
  name: '',
  email: '',
  phone: '',
  cv: '',
  documents: '',
  rodo: false,
  regulations: false,
});

useEffect(() => {
  if (location.data) {
    changeData({
      ...data,
      name: location.data.name
    });
  }
}, []);

Ideally you should be defining individual items in the state something like below:

const [name, changeName] = useState('');
const [email, changeEmail] = useState('');
....
const [rodo, changeRodo] = useState(false);

And then in your useEffect hook you will change individual item like below:

useEffect(() => {
  if (location.data) {
    changeName(location.data.name);
  }
}, []);

This way, name is always defined, and thus the <input />s value was always set, or controlled. Read on

Rikin
  • 5,351
  • 2
  • 15
  • 22