Clear form after submit React - reactjs

In my app, I am making a form to add animal for adoption with React. The data is stored in Mongo if this is important to know.
But I can not figure out how, I tried to look and nothing works for me. Maybe there is something wrong with the form. I would be very thankful if someone can tell me how to clear or reset the form after submitting. I simplified it so it would be easy to see what I have. Here is my form:
import React, { useState } from "react";
import { useDispatch } from "react-redux";
import { addAnimal } from "../redux/actions";
const AddAnimalForm = () => {
const dispatch = useDispatch();
const [name, setName] = useState("");
const [kind, setKind] = useState("");
const [displayForm, setDisplayForm] = useState(false);
const dispatchAddAnimal = () => {
dispatch(
addAnimal(
{
name,
kind
},
"_id name kind sex age city author phone info"
)
);
};
const onShowButtonClicked = () => {
setDisplayForm(true);
};
const onHideButtonClicked = () => {
setDisplayForm(false);
};
return !displayForm ? (
<button className="col-xs-12 col-md-3" onClick={onShowButtonClicked}>
add
</button>
) : (
<React.Fragment>
<div className="col-xs-12 col-sm-9">
<button className="col-xs-12 col-md-3" onClick={onHideButtonClicked}>
hide{" "}
</button>
<form>
<div className="form-row">
<div className="form-group col-md-6">
<label htmlFor="animal-name">name</label>
<input
type="text"
className="form-control"
onChange={e => setName(e.target.value)}
id="animal-name"
/>
</div>
<div className="form-group col-md-6">
<label htmlFor="kind">kind</label>
<input
type="text"
onChange={e => setKind(e.target.value)}
className="form-control"
id="kind"
/>
</div>
</div>
<button
type="button"
className="btn btn-primary"
onClick={dispatchAddAnimal}
>
add animal
</button>
</form>
</div>
</React.Fragment>
);
};
export default AddAnimalForm;

define a variable at the top just below you imports
let exampleRef = React.createRef()
hi first you have to create a reference to that form like this :-
<form ref={(el) => myFormRef = el;}>
<input />
<input />
...
<input />
</form>
and after that, while submitting your form you just use the reset() method provided by the form reference like this
const dispatchAddAnimal = () => {
myFormRef.reset();
dispatch(
addAnimal(
{
name,
kind
},
"_id name kind sex age city author phone info"
)
);
};
let me know if it works for you or not.
there is also a great library React Advanced Form which handle lots of thing on its own like validation and other stuff check this out if you feel free

Related

Unsure where to put a map

I am currently working on a component to update routines. I am recieving the error message that activity is undefined, and I think I know that the problem is that I was trying to use it before defining it, but everywhere I try to put the .map() causes the code to break. Here's what the file looks like:
import React, { useState, useEffect, Fragment } from "react";
import { getAllActivities } from "../api";
import { attachActivityToRoutine } from "../api";
const UpdateRoutine = ({ routineData, setIsShown }) => {
const handleChange = (event) => {
setValue(event.target.value);
};
const [allActivities, setAllActivities] = useState([]);
console.log(allActivities, 'line 10')
return (
<div>
<form onSubmit>
<label htmlFor="updateRoutine">Update Name:</label>
<input />
<button type="submit">Submit</button>
</form>
<form onSubmit>
<label htmlFor="updateGoal">Update Goal:</label>
<input></input>
<button type="submit">Submit</button>
</form>
<form onSubmit="handleSubmit">
<fieldset>
<label htmlFor="selectActivity">
Activity <span className="selectActivity">({allActivities})</span>
</label>
(v This select is the problem area v)
<select
name="activity"
id="selectActivity"
value={activity}
onChange={(event) => setAllActivities(event.target.value)}
>
{getAllActivities.map((activity, idx) => (
<option key={`${idx}:${activity.name}`} value={activity.name}>
{activity.name}
</option>
))}
</select>
</fieldset>
<button type="submit">Search</button>
</form>
<button
onClick={(event) => {
setIsShown(false);
}}
>
Nevermind
</button>
</div>
);
};
export default UpdateRoutine;
Any advice would be greatly appreciated!

how to get the data from a component within a form in react

I have a with the following structure in react...
<form>
<div>
<label>Name</label>
<input />
</div>
<div>
<label>Age</label>
<input />
</div>
<div>
<label>Gender</label>
<input />
</div>
<AddressComponent />
<button type='submit'>
Submit
</button>
</form>
Does anyone know if there is a way for me to pass the AddressComponent data up to the parent form component onSubmit? The AddressComponent has a lot of state to manage and a load of functions and it appears a few more times across my website and so I don't want to keep repeating the same code over and over again.
Anyone know if there's a way for me to pass the AddressComponent state up to the parent form component onSubmit?
you can use ref to get access to the child functions so:
const AddressComponent = ({}, ref) => {
const [data, setData] = useState();
useImperativeHandle(ref, () => ({
getData: getData,
}));
const getData = () => {
return data;
}
return <div></div>;
};
export default React.forwardRef(AddressComponent);
and you can get data in your parent and in submit like this:
const ParentComponent = () => {
const AddressRef = useRef(null);
const handleSubmit = (event) => {
event.preventDefault();
const data = AddressRef.current.getData();
}
return (
<form onSubmit={handleSubmit}>
<div>
<label>Name</label>
<input />
</div>
<div>
<label>Age</label>
<input />
</div>
<div>
<label>Gender</label>
<input />
</div>
<AddressComponent ref={AddressRef} />
<button type='submit'>
Submit
</button>
</form>
)
}

I’m trying to save data on the database but it is saving each input change

import React, {useState, useEffect} from 'react'
import { NoMoralisContextProviderError } from 'react-moralis';
import './css/createpost.css'
import { useMoralis } from "react-moralis";
function CreatePost() {
const [title, setTitle] = useState("")
const [content, setContent] = useState("")
const { Moralis, isInitialized } = useMoralis();
const createNewPost = (e, title, content) => {
e.preventDefault()
const newPost = Moralis.Object.extend("Posts");
const post = new newPost();
post.set("title", title);
post.set("content", content);
post.save();
return post;
}
return (
<div>
<div>
<form action="#" className="createpost">
<div class="data">
<label>Title</label>
<input type="text" required onChange={(e) => setTitle(e.target.value)}/>
</div>
<div class="data">
<label>Content</label>
<input type="text" required onChange={(e) => setContent(e.target.value)}/>
</div>
<div class="btn">
<div class="inner"></div>
<button type="submit" onClick={createNewPost(e, title, content)}>Submit Post</button>
</div>
</form>
</div>
</div>
)
}
export default CreatePost
I’m trying to save the data to the database, but after each input change it is saved. So if I type “hello” it saves “h”, “he”, “hel”, “hell”, “hello” and I would like it to just save hello once. Not each input change. Can someone help me fix this issue?
I'm trying to save this to moralis database, but i think the error is that the function is called multiple times.
Wrap your handler to arrow function
<button type="submit" onClick={() => createNewPost(e, title, content)}>Submit Post</button>

e.preventDefault() not working in my react app which is causing unnessary redirect

Hi I am trying to create a react-redux form and my e.preventDefault() is not working which i causing a redirect everytime I press an enter key.
Could someone look in my code and tell me where am I going wrong:
I am having an input field and when I am giving an e.preventDefault(), but for some reason its redirecting.
import React, { useState } from "react";
import { useDispatch } from "react-redux";
function InputField() {
let [task, setTask] = useState("");
const dispatch = useDispatch();
let onTaskAdd = (e) => {
setTask(e.target.value);
};
let addTaskinTaskManager = () => {
dispatch({ type: "ADD_TASK", payload: task });
setTask("");
};
return (
<div className="container-fluid mt-5">
<div className="row justify-content-center">
<div className="col-md-6">
<form>
<div className="form-group row">
<label className="col-md-2 col-form-label">Task:</label>
<div className="col-md-10">
<input
type="text"
id="task"
name="task"
className="form-control"
placeholder="eg, singing"
value={task}
onChange={(e) => {
e.preventDefault();
e.stopPropagation();
onTaskAdd(e);
}}
/>
</div>
</div>
</form>
</div>
<div className="col-md-2">
<button
type="button"
onClick={addTaskinTaskManager}
className="btn btn-primary"
>
Add Task
</button>
</div>
</div>
</div>
);
}
export default InputField;

Trying to get a innerhtml functionality to work in react todo list

I am aiming for new tasks to show as user clicks "add task", simple I know, but still learning react.
My goal was to use a ternary operator until its no longer null, and then map through the array each time a user clicks add task.
Issue:
I believe the renderTasks array isn't set by the time it tries to map over it, I get an error...
renderTasks.map is not a function
Is there a way I could utilize the useEffect for what I am trying to do, or any better ideas that could help? Thanks
Here's the code snippet of App.js
function App() {
const [tasks, setTasks] = useState([]);
const [renderTasks, setRenderTasks] = useState(null);
const handleAddTask = () => {
setRenderTasks(tasks);
};
const handleOnChange = (e) => {
setTasks({
...tasks,
[e.target.name]: e.target.value,
});
};
return (
<>
<div className="overview">
<label className="my-todos">My Todos</label>
<div className="input-div">
<div className="input-container">
<label className="title-desc">Title</label>
<input
name="title"
onChange={handleOnChange}
className="input-values"
type="text"
></input>
</div>
<div className="input-container">
<label className="title-desc">Description</label>
<input
name="description"
onChange={handleOnChange}
className="input-values"
type="text"
></input>
</div>
<button onClick={handleAddTask} className="add-task">
Add Task
</button>
</div>
{renderTasks !== null ? (
<ul>
{renderTasks.map((x) => {
return <li>{x.title - x.description}</li>;
})}
</ul>
) : null}
</div>
</>
);
}
export default App;
There were few issues in your implementation like how you destructing tasks, trying to access an object as an array and abusing the useState. You don't need useEffect or two useState to do the trick.
import React from "react";
import React, { useState } from 'react';
import "./style.css";
function App() {
const [tasks, setTasks] = useState([]);
const task = {};
const handleOnChange = (e) => {
task[e.target.name] = e.target.value;
};
const onClickHandler = (e)=>{
(task.title) && setTasks( [...tasks, task]);
}
return (
<>
<div className="overview">
<label className="my-todos">My Todos</label>
<div className="input-div">
<div className="input-container">
<label className="title-desc">Title</label>
<input
name="title"
onChange={handleOnChange}
className="input-values"
type="text"
></input>
</div>
<div className="input-container">
<label className="title-desc">Description</label>
<input
name="description"
onChange={handleOnChange}
className="input-values"
type="text"
></input>
</div>
<button onClick={onClickHandler} className="add-task">
Add Task
</button>
</div>
<ul>
{tasks.map((x) => {return <li>{x.title} - {x.description}</li> })}
</ul>
</div>
</>
);
}
export default App;
Even though you are initialising tasks to be an array, in handleOnChange you are setting it to an Object like this -
setTasks({
...tasks,
[e.target.name]: e.target.value,
});
This same tasks object you are trying to set for renderTasks in handleAddTask. So renderTasks is assigned to an Object and not an array and only arrays have map function and hence you are facing the issue renderTasks.map is not a function error
Try doing
Object.keys(renderTasks).map((x) => {
return <li>{x.title - x.description}</li>;
})

Resources