1

Issue:

I am unable to change the state duynamically. I need to change the state object's key as per the input field's "name" attribute.

Code:

const addressValue = (e) => {
        setAddress(state => ({
            ...state,
            [e.target.name]: e.target.value
        }));
    };
/****************************************************************
* giving error while typing "Cannot read property 'name' of null"
*****************************************************************/
<form onSubmit={submitHandler}>
        <div className="form-group">
            <input id="address-line-1" className="form-control" value={address.line1}
                onChange={addressValue} name="line1" type="text" placeholder="Line 1" />
        </div>
        <div className="form-group">
            <input id="address-line-2" className="form-control" value={address.line2}
                onChange={addressValue} name="line2" type="text" placeholder="Line 2" />
        </div>
</form>

Object's initial value

{
line1 : "CA",
line2 : "US"
}
3
  • 1
    Read here about reacts synthetic events. Basically, because you're using a functional update, the event has been reset before it gets used. Solution would be to use e.persist() or save the relevant values to other variables outside the event object. Or another option would be to not use a functional update, since your new state is not derived from the previous state. Commented Jun 25, 2020 at 20:33
  • Does this answer your question? Reactjs - TypeError: Cannot read property 'value' of null Commented Jun 25, 2020 at 20:36
  • Thank you so much! It worked and I learned something new. I really respect people like you who take time to help others. Commented Jun 25, 2020 at 20:36

2 Answers 2

0

Thanks to Brian Thompson. Since I was using a functional update, the event was resetting before it was getting used. So, I used e.persist().

const addressValue = (e) => {
    e.persist();
    setAddress(state => ({
        ...state,
        [e.target.name]: e.target.value
    }));
};
Sign up to request clarification or add additional context in comments.

1 Comment

const addressValue = ({target;{name,value}}) => { would be easier, Brian also said: or save the relevant values to other variables outside the event object.
0

As an alternative what you can do is create a custom useForm hook like so:

import { useState } from 'react';

export const useForm = initialValues => {
    const [values, setValues] = useState(initialValues);

    return {
        values,
        handleChange: e => {
            setValues({
                ...values,
                [e.target.name]: e.target.value,
            });
        },
        reset: () => setValues(initialValues),
    };
};

Then you can import and use it in any form component: (for example here's a sign in form)

import React from 'react';
import { useForm } from '../hooks/useForm';
import history from '../history';

export default function SignInForm() {
    const { values, handleChange, reset } = useForm({ email: '', password: '' });

    const handleSubmit = e => {
        e.preventDefault();
        // POST request or however you handle the submission
        reset();
        history.goBack();
    };

    return (
        <form onSubmit={handleSubmit} className='SignIn__form'>
            <input
                className='SignIn__form--input'
                type='email'
                name='email'
                placeholder='Enter your email...'
                onChange={handleChange}
                value={values.email}
            />
            <input
                className='SignIn__form--input'
                type='password'
                name='password'
                placeholder='Enter your password...'
                onChange={handleChange}
                value={values.password}
            />
            <button className='Button' type='submit'>
                Sign In
            </button>
        </form>
    );
}

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.