0

I am trying to save the input given by the user using the input tag, to an array in the state. My App.js looks like this

class App extends Component {
  
  state = {
    generalInfo: [
      {
        email : "",
        name: "",
        contactNumber: "",
      }
    ],
  }

 handleGeneralSubmit = (e) => {
    e.preventDefault();

    console.log("general submit clicked");   //this function should contain code to take input and store.
  }


 render() { 
    return ( 
      <div>
        <GeneralInfo onGeneralSubmit={this.handleGeneralSubmit} onGeneralEdit={this.handleGeneralEdit} />
      </div>
     );
  }
}
 
export default App;


--------------------
another file generalinfo.jsx


class GeneralInfo extends Component {
  render() {
    const { onGeneralSubmit, onGeneralEdit } = this.props;

    return (
      <div>
   
        <form>
          <div className="form-group m-4">
            <label htmlFor="InputEmail1">Email address</label>
            <input
              type="email"
              className="form-control"
              id="InputEmail1"
              aria-describedby="emailHelp"
              placeholder="Enter email"
            />
            <small id="emailHelp" className="form-text text-muted">
              We'll never share your email with anyone else.
            </small>
          </div>
          <div className="form-group m-4">
            <label htmlFor="inputAddress">Name :</label>
            <input
              type="text"
              className="form-control"
              id="inputName"
              placeholder="Full Name"
            />
          </div>
          <div className="form-group m-4">
            <label htmlFor="inputAddress">Phone Number :</label>
            <input
              type="text"
              className="form-control"
              id="inputContactNumber"
              placeholder="Contact Number"
            />
          </div>
          <button
            onClick={onGeneralSubmit}
            type="submit"
            className="btn btn-primary m-4"
          >
            Submit
          </button>
          <button
            onClick={onGeneralEdit}
            type="submit"
            className="btn btn-warning m-4 "
             //disabled={this.props.generalInfo.length === 0 ? "disabled" : " "}
          >
            Edit
          </button>
        </form>
      </div>
    );
  }
}

export default GeneralInfo;

Can anyone help me with this, I am still new to handling states. And I am not getting what exactly should be code in the function. I tried to add e.target.value to the state, but it is showing error.

3 Answers 3

1
class App extends Component {
  state = {
    generalInfo: [
      {
        email : "",
        name: "",
        contactNumber: "",
      }
    ],
  }

 handleGeneralSubmit = (e, label) => {
    e.preventDefault();

    console.log("general submit clicked");  
    let prevState = this.state;
    prevState.generalInfo[0][label] = e.target.value;
    console.log(prevState)  // to see the new value
    this.setState(prevState);
  }


 render() { 
    return ( 
      <div>
        <GeneralInfo onGeneralSubmit={this.handleGeneralSubmit} onGeneralEdit={this.handleGeneralEdit} />
      </div>
     );
  }
}
 
export default App;


--------------------
another file generalinfo.jsx


class GeneralInfo extends Component {
  render() {
    const { onGeneralSubmit, onGeneralEdit } = this.props;

    return (
      <div>
   
        <form>
          <div className="form-group m-4">
            <label htmlFor="InputEmail1">Email address</label>
            <input
              type="email"
              className="form-control"
              id="InputEmail1"
              aria-describedby="emailHelp"
              placeholder="Enter email"
              onChange={(e)=>onGeneralEdit(e, 'email')}
            />
            <small id="emailHelp" className="form-text text-muted">
              We'll never share your email with anyone else.
            </small>
          </div>
          <div className="form-group m-4">
            <label htmlFor="inputAddress">Name :</label>
            <input
              type="text"
              className="form-control"
              id="inputName"
              placeholder="Full Name"
            onChange={(e)=>onGeneralEdit(e, 'name')}
            />
          </div>
          <div className="form-group m-4">
            <label htmlFor="inputAddress">Phone Number :</label>
            <input
              type="text"
              className="form-control"
              id="inputContactNumber"
              placeholder="Contact Number"
              onChange={(e)=>onGeneralEdit(e, 'contactNumber')}

            />
          </div>
          <button
            onClick={onGeneralSubmit}
            type="submit"
            className="btn btn-primary m-4"
          >
            Submit
          </button>
        </form>
      </div>
    );
  }
}

export default GeneralInfo;

No need for an additional edit button Type the values in textbox it will update state in the parent component

but I don't understand why you need the values in an array,

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

2 Comments

I was trying to build a resume template, to understand react in a better way, so in order to save the details of users, I used this array to save their input.
ok, use above code to solve your problem
0

GeneralInfo should really be maintaining its own form state and then, only when the button is clicked, pass that form data to the parent as an object. You can then add that to the main array.

I've used more modern React methods here: functional components, and useState but I hope you understand what's going on.

const { useEffect, useState } = React;

// We accept a submit function in the component props
function GeneralInfo({ submit }) {

  const initialState = { email: '', name: '', number: '' };

  // Initialise the state
  const [ form, setForm ] = useState(initialState);
 
  // When any of the inputs change get the
  // value and name, and use those variables to
  // update the form object in state
  function handleChange(e) {
    const { value, name } = e.target;
    setForm({ ...form, [name]: value });
  }
 
  // When the button is called call the
  // `handleSubmit` function passed in with props
  function handleSubmit() {
    submit(form);
  }
 
  return (
    <div onChange={handleChange}>
      <label>Email: <input name="email" type="email" /></label>
      <label>Name: <input name="name" type="text" /></label>
      <label>Number: <input name="number" type="tel" /></label>
      <button onClick={handleSubmit}>Submit</button>
    </div>
  );

}

function Example() {

  const [ data, setData ] = useState([]);

  // Once the function is called with the form
  // object, update the state with it.
  function handleSubmit(obj) {
    setData([...data, obj]);
  }

  // Here I'm just using `useEffect` to watch
  // for changes in state and logging the result
  useEffect(() => {
    if (data.length) console.log(data);
  }, [data]);

  return (
    <GeneralInfo submit={handleSubmit} />
  );

};

// Render it
ReactDOM.render(
  <Example />,
  document.getElementById("react")
);
label {display: block;}
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/17.0.1/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/17.0.1/umd/react-dom.production.min.js"></script>
<div id="react"></div>

Comments

0

First, in React, you should create a state to store each inputs value and then change it on Input's onChange prop. You can check the example here: https://codesandbox.io/s/ecstatic-cdn-lcmes?file=/src/App.js

Now, after you have stored values in the state you can create an object of the value that you want to add to the array. You should it in your function called handleGeneralSubmit.

It should look something like this:

handleGeneralSubmit = (e) => {
  e.preventDefault(); 
  this.setState(({generalInfo, email, name, contactNumber}) => {
      generalInfo: [...generalInfo, { email, name, contactNumber }]
  })
}

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.