1

I'm trying to have the data from the textarea in the form be stored in an array once the user hits the submit button. I'm working with only functional components. Do I need to use preventDefault() to stop the page from refreshing in order for the data to be transferred into an array? I need the form to still clear after the user hits submit so if I use preventDefault() I will likely need to create a new component to reset the textarea.

I appreciate any ideas! Thank you for your time!

 function App () { 
         const [value, setValue] = useState("");
         const [entrylist, setEntry] = useState([]);
         
         
            
            const handleChange = () => {
            setValue([value])
            console.log(value)
        } 
    
            const readNWrite = () => {
                setEntry([entrylist])
                entrylist.push(value)
    
            } 
    
        return (
            <div>
            <div> Insert Entry  </div> 
    
            <form class="entryForm"    >
                <label for="newEntryId"> 
                <span>New Entry:</span>
                <textarea  type="text" id="newEntryId" name="newEntryName" rows="30" cols="75" defaultValue = {"What's on your mind?"}  onChange={(e)=> { 
                handleChange(e.target.value);
                }} />
                </label>
                <button onClick={readNWrite}>Submit</button>
           
            </form>
            </div>
        )
        
    }

4 Answers 4

1

Looks like you're trying to modify entrylist directly which isn't something you can do. Instead create a new array and push your value onto that, then set the value of entryList using this new value.

const readNWrite = () => {
   const updatedList = [...entrylist];
   updatedList.push(value);

   setEntry(updatedList);
} 
Sign up to request clarification or add additional context in comments.

Comments

1

I don't think you require a controlled component (textarea) over here as what you are doing is essentially resetting the data present inside it on submit. Therefore, there is no harm in using an uncontrolled component, thats why, value useState hook and handleChange in your textarea is not required.

I don't understand exact what you are trying to do with readNWrite, I suppose you want to put your text data as an array element in that. In that case you are not doing it the right way.

Yeah, you need to call preventDefault to stop the refresh and clear the textarea yourself.

you need to call the readNWrite function in onSubmit for the form, no need to put it in the button and change the button type as submit.

export default function App() {
  const [entrylist, setEntry] = useState([]);

  const readNWrite = event => {
    setEntry([...entrylist, event.target[0].value]);
    event.target[0].value="";
    event.preventDefault();
  };

  return (
    <div>
      <div> Insert Entry </div>

      <form class="entryForm" onSubmit={readNWrite}>
        <label for="newEntryId">
          <span>New Entry:</span>
          <textarea
            type="text"
            id="newEntryId"
            name="newEntryName"
            rows="30"
            cols="75"
            defaultValue={"What's on your mind?"}
          />
        </label>
        <button type="submit">Submit</button>
      </form>
    </div>
  );
}

Comments

1

You'll need to handle the onSubmit event on the form. And like you suspected, you'll need to call event.preventDefault() to prevent the form from reloading the page.

Extract the values from the form with the FormData constructor. Then loop over the formdata and add each entry to a new array.

Update the state with the new entries.

function App() {
  const [entries, setEntries] = useState([]);

  const handleSubmit = (event) => {
    event.preventDefault();
    const formData = new FormData(event.target);

    const newEntries = [];
    for (const [name, value] of formData) {
      newEntries.push({
        name,
        value
      });
    }

    setEntries(newEntries);
  };

  /**
   * This is here to log the changed entrylist state.
   */
  useEffect(() => {
    console.log(entries);
  }, [entries]);

  return (
    <div>
      <div>Insert Entry</div> 
      <form 
        class="entryForm"
        onSubmit={handleSubmit}
      >
        <label for="newEntryId"> 
          <span>New Entry:</span>
          <textarea 
            id="newEntryId" 
            name="newEntryName" 
            rows="30" 
            cols="75" 
            defaultValue={"What's on your mind?"}
          />
        </label>

        <button
          type="submit"
          onClick={readNWrite}
        >Submit</button>
      </form>
    </div>
  );
}

2 Comments

Thank you for your help! Is formValues supposed to be formData? If I use formValues it is not defined and if I use formData in its place I get an error stating the formData.push is not a function.
My bad, I forgot to change a variable. It should have been newEntries
0
  1. You do need e.preventDefault() to prevent form's default action from happening, and that should be added to your readNWrite event handler.

  2. You don't need to create a new component to reset your textarea, because from what I can see from your code, you are storing the text into [entrylist]. While the change in textarea is handled by handleChange, where e.target.value is passed in, what you can do is after push the current text to the array, you can set the value to an empty string like this,

            const handleChange = (e) => {
                setValue(e.target.value);
                console.log(value);
            } 
    
            const readNWrite = () => {
                setEntry([entrylist]);
                entrylist.push(value);
                setValue("");
            } 

1 Comment

It's bad practice to directly mutate an array in state. You should avoid "push" (mutates array directly) and use "concat" or spread syntax instead (returns new array which you can then setState with). Source: React Docs react.dev/learn/updating-arrays-in-state

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.