skip to Main Content

I have a state variable which is an empty array

const [boxes, setBoxes] = useState([]);
const [showAddGalley,setShowAddGalley]=useState({galleyNo:""});

I have a function which takes input from a form and on each time i submit i need to set the boxes array with object from the form,

my submit function is

      const onSubmitGalleyBoxes=(e,updated)=>{
        
            if(updated){
              setBoxes((prev)=>{return {...prev,`${showAddGalley.galleyNo}`:{updated}}})
            }
            
        
                  }

my intention is got get the boxes array on each submit like the below

     const  boxes=[{id: "Galley10", galleyNo: "440S", galleyItem: "Veg Meals"},
        {id: "Galley11", galleyNo: "340S", galleyItem: "Non Veg Meals"}
        ] 

my updated object in the function in onSubmitGalleyBoxes is,

const updated={galleyNo: "340S", galleyItem: "Non Veg Meals"}

the setBoxes i am doing in the onSubmitGalleyBoxes doesn’t seems to work what is wrong here

2

Answers


  1. This will correctly update your boxes state variable:

    if you just want to push data into the array

    const newData = {... your data}
    setBoxes(( currentValue ) => [ ...currentValue, newData ])
    

    or if you want to update data inside value:

    const newData = { ...your data }
    setBoxes(( currentValue ) => {
    
      return currentValue.map(value => {
    
        // update only desired `galeryNo`
        if(value.galleyNo === newData.galleyNo) return newData
    
        // returns unchanged value
        return value
      })
    })
    
    Login or Signup to reply.
  2. You have a function that – on form submission – takes the object generated by the form and updates the boxes array with that object.

    The correct syntax for this would be setBoxes(prev => [...prev, object]);.

    Here’s a small working example that uses a GalleyForm component (which maintains its own state), and displays the boxes state whenever it’s updated with a new form object.

    const { useEffect, useState } = React;
    
    function Example() {
    
      // Initialise boxes state
      const [ boxes, setBoxes ] = useState([]);
    
      // Show boxes state after update
      useEffect(() => {
        if (boxes.length) {
          console.log(JSON.stringify(boxes));
        }
      }, [boxes]);
    
      // Accepts a two-key/value form object and
      // updates the boxes state with it.
      // For convenience in this example it creates
      // a bespoke id based on the length of
      // the current boxes state
      function handleForm(form) {
        setBoxes(prev => {
          return [...prev, {
            id: boxes.length + 1,
            ...form
          }];
        });
      }
    
      // Render a GalleyForm component passing down
      // a handler
      return (
        <GalleyForm handleForm={handleForm} />
      );
    
    }
    
    // Accepts the handleForm handler
    function GalleyForm({ handleForm }) {
      
      // Initialise the form state as an empty object
      const [ form, setForm ] = useState({});
        
      // Calls the handleForm handler with the
      // form object
      function handleSubmit() {
        handleForm(form);
      }
      
      // Updates the form state using the name/value
      // from the input
      function handleInput(e) {
        const { name, value } = e.target;
        setForm(prev => {
          return {...prev, [name]: value }
        });
      }
      
      // Render a series of input fields
      return (
        <fieldset>
          <legend>Add gallery details</legend>
          <div>
            <label htmlFor="galleryNo">No.</label>
            <input
              id="galleryNo"
              name="galleyNo"
              type="text"
              value={form.galleyNo || ''}
              onInput={handleInput}
            />
          </div>
          <div>
            <label htmlFor="galleryItem">Item</label>
            <input
              name="galleyItem"
              type="text"
              value={form.galleyItem || ''}
              onInput={handleInput}
            />
          </div>
          <button
            type="button"
            onClick={handleSubmit}
          >Submit
          </button>
        </fieldset>
      );
    
    }
    
    const node = document.getElementById('root');
    const root = ReactDOM.createRoot(node);
    root.render(<Example />);
    fieldset div { display: flex; }
    label { width: 50px; }
    button, fieldset div:not(:first-child) { margin-top: 1rem; }
    <script src="https://cdnjs.cloudflare.com/ajax/libs/react/18.2.0/umd/react.development.min.js"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/18.2.0/umd/react-dom.development.min.js"></script>
    <div id="root"></div>
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search