Home > Software engineering >  How do I set initial values from state to dynamically added inputs?
How do I set initial values from state to dynamically added inputs?

Time:10-26

I have dynamic inputs I can add and save to the state, but I want to be able to set initial values, to begin with. I would like to update those values and resave those edits at any time.

Here is the full code below. You can also check out the SANDBOX HERE

    import { useState } from "react";

             // I want to use these as my initial values. This is the object in my database:

const InitialValuesDB = [{name: "John", age: "108"}, {name: "Jane", age: "204"}]

function Form() {
  const [formFields, setFormFields] = useState([{ name: "", age: "" }]);

            // I can iterate the values like this:

  function LoggingMap() {
       InitialValuesDB.map((item, i) => {
           console.log('Index:', i, 'name:', item.name);
           console.log(item.name)
           
           // But I can't access theme outside of this function:
       });
   }
   LoggingMap()

  const handleFormChange = (event, index) => {
    let data = [...formFields];
    data[index][event.target.name] = event.target.value;
    setFormFields(data);
  };

  const submit = (e) => {
    e.preventDefault();
    console.log(formFields);
  };

  const addFields = () => {
    let object = {
      name: "",
      age: "",
    };
    setFormFields([...formFields, object]);
  };

  const removeFields = (index) => {
    let data = [...formFields];
    data.splice(index, 1);
    setFormFields(data);
  };

  return (
    <div className="App">
      <form onSubmit={submit}>
        {formFields.map((form, index) => {
          return (
            <div key={index}>
                
            {/* But how do I set my initial values (item.name, item.age) as initial values, so that when I reload, the saved values return */}

              <input
                name="name"
                placeholder="Name"
                onChange={(event) => handleFormChange(event, index)}
                value={form.name}
              />
              <input
                name="age"
                placeholder="Age"
                onChange={(event) => handleFormChange(event, index)}
                value={form.age}
              />
              <button onClick={() => removeFields(index)}>Remove</button>
            </div>
          );
        })}
      </form>
      <button onClick={addFields}>Add More..</button>
      <br />
      <button onClick={submit}>Submit</button>
    </div>
  );
}

export default Form;

Expected Results

If I have 5 inputs with values submitted, I want those values saved in a state and on reload, have those as initial values. I want to edit the inputs, resave that, etc.

CodePudding user response:

For initially putting the items

you should replace your useState with the initial value.

Replace this with:

const [formFields, setFormFields] = useState([{ name: "", age: "" }]);

This

const [formFields, setFormFields] = useState(InitialValuesDB);

CodePudding user response:

Use localStorage, write the state values to localStorage when state updates and read from localStorage on initial render to set the state back to what it was previously before the reload.

EDIT: Try out the following code and see if it fits your usecase.

import { useEffect, useState } from "react";

// I want to use these as my initial values. This is the object in my database:

const InitialValuesDB = [
  { name: "John", age: "108" },
  { name: "Jane", age: "204" },
];

function Form() {
  const [formFields, setFormFields] = useState(JSON.parse(localStorage.getItem("key"))|| InitialValuesDB || [{ name: "", age: "" }]);
  useEffect(() => {
    localStorage.setItem("key", JSON.stringify(formFields))
  },[formFields])
  // I can iterate the values like this:

  function LoggingMap() {
    InitialValuesDB.map((item, i) => {
      console.log("Index:", i, "name:", item.name);
      console.log(item.name);

      // But I can't access theme outside of this function:
    });
  }
  LoggingMap();

  const handleFormChange = (event, index) => {
    let data = [...formFields];
    data[index][event.target.name] = event.target.value;
    setFormFields(data);
  };

  const submit = (e) => {
    e.preventDefault();
    console.log(formFields);
  };

  const addFields = () => {
    let object = {
      name: "",
      age: "",
    };
    setFormFields([...formFields, object]);
  };

  const removeFields = (index) => {
    let data = [...formFields];
    data.splice(index, 1);
    setFormFields(data);
  };

  return (
    <div className="App">
      <form onSubmit={submit}>
        {formFields.map((form, index) => {
          return (
            <div key={index}>
              {/* But how do I set my initial values (item.name, item.age) as initial values, so that when I reload, the saved values return */}

              <input
                name="name"
                placeholder="Name"
                onChange={(event) => handleFormChange(event, index)}
                value={form.name}
              />
              <input
                name="age"
                placeholder="Age"
                onChange={(event) => handleFormChange(event, index)}
                value={form.age}
              />
              <button onClick={() => removeFields(index)}>Remove</button>
            </div>
          );
        })}
      </form>
      <button onClick={addFields}>Add More..</button>
      <br />
      <button onClick={submit}>Submit</button>
    </div>
  );
}

export default Form;

CodePudding user response:

I think I don't fully understand you question but here my solution.

Just add useEffect after your removeFields function

useEffect(() => {
    setFormFields(InitialValuesDB)
}, [])

CodePudding user response:

Use usefieldarry api of react hook form to maintain dynamic input fields in react form that's great and very simple.

Here is working code sandbox link

https://codesandbox.io/s/nice-swartz-7exhy2?file=/src/form.jsx

Note: I have no knowledge of typescript but i implement it in JavaScript I hope you can convert it into typescript

  • Related