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>
3
  • 1
    There is no input in the code shown. Commented Aug 30, 2019 at 12:32
  • Possible duplicate of stackoverflow.com/questions/47012169/… Commented Aug 30, 2019 at 12:41
  • You should use useReducer instead useState for complex objects offical docs Commented Aug 30, 2019 at 12:41

1 Answer 1

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

Sign up to request clarification or add additional context in comments.

6 Comments

Cautiion: This will only run in "componentDidMount" lifecycle. because of}, []);
And how to pass all data?? not only location.data.name but all data.location? How to update all state ??
While you are right, this does not answer the question.
@JonasWilms the issue is OP is resetting the data and in useEffect which is causing prior known properties to null and thus React raises the issue.
Yes, and exactly that piece of information was missing. I added that.
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.