2

I am new and still practicing in reactjs. I am having a problem in my input form, whenever I type any key I always get TypeError: Cannot read property 'value' of null

this is my code:

import React, { useState } from 'react';

export default function FormPractice() {
const [isDefault, setIsDefault] = useState('');
const [balance, setBalance] = useState({amount: null});

return (
  <div className="input">
    <input placeholder="enter balance here" onChange={e => setBalance(form => ({...form, [e.target.value]: e.target.value}))} value={isDefault}/>
  </div>
)
}

Thanks for the help.

1
  • I tried it but I cannot input any key Commented May 18, 2020 at 13:51

1 Answer 1

1

React re-uses events. When you use a functional update, by the time the function is called, the event has already been wiped for reuse. To use the event within the functional update you would need to call e.persist() which will take that event out of the reuse pool and let it keep its values.

To keep it inline, it would look like this:

onChange={e => {e.persist(); setBalance(form => ({...form, [e.target.value]: e.target.value}))}}

Or to make it more readable, move it into its own function:

const onChange = (e) => {
  e.persist();
  setBalance(form => ({...form, [e.target.value]: e.target.value}));
}

However, the simplest available solution would be to not use the functional update at all. You are replacing state values, but you are not setting any values derived from the previous state. So it is safe to use a normal update:

onChange={e => setBalance({...balance, [e.target.value]: e.target.value})}

Now the event reuse is a non-issue.

Side note: [e.target.value]: e.target.value this doesn't really make sense. You're setting an object key with the name of the new value to the same value.

It seems like maybe you've seen [e.target.name]: e.target.value before and modified it. I would suggest using the name, and then giving the input the name of the property you want to update.

Here is a simplified example:

const {useState, useEffect} = React;

const Example = () => {
  const [state, setState] = useState({ input1: '' });
   
  const onChange = (e) => {
    setState({[e.target.name]: e.target.value});
  }
   
   return (
    <input 
      name="input1"
      placeholder="enter balance here" 
      onChange={onChange} 
      value={state.input1}
    />
  );
}

ReactDOM.render(<Example />, document.getElementById('root'));
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.8.4/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.8.4/umd/react-dom.production.min.js"></script>
<div id="root"></div>

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

Comments

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.