Next js - How to Update or Clear/Reset const array value? - reactjs

I am Beginner to fronted development.I am working on next js project.
My task is to display result on form submit, Which i have done. Next task is to reset form and also clear/reset search result on button click. I am not able to find the solution, how do i can reset/clear that.
Here is What i have tried so far:
UPDATED
import { useForm } from 'react-hook-form';
import { useState } from "react";
import { yupResolver } from '#hookform/resolvers/yup';
import * as Yup from 'yup';
const userEndPoint = '/api/users/';
const { searchResults = [] } = [];
export default function Home() {
const [userSearchResults, setUserSearchResults] = useState({ result: [] });
const validationSchema = Yup.object().shape({
searchQuery: Yup.string()
.required('This field is required'),
});
const formOptions = { resolver: yupResolver(validationSchema) };
const { errors } = formState;
const resetFunction = async () => {
setUserSearchResults([]);
}
const onSubmitFunction = async (event) => {
console.log("search query =====> ",event.searchQuery)
const response = await fetch(userEndPoint+event.searchQuery)
const data = await response.json()
searchResults = data.results;
userSearchResults = data.results;
};
return (
<div className="card m-3">
<h5 className="card-header">Example App</h5>
<div className="card-body">
<form onSubmit={handleSubmit(onSubmitFunction)}>
<div className="form-row row">
<div className="col-6 d-flex align-items-center">
<input name="searchQuery" type="text" {...register('searchQuery')} className={`form-control ${errors.searchQuery ? 'is-invalid' : ''}`} />
<div className="invalid-feedback">{errors.searchQuery?.message}</div>
</div>
<div className="col-6">
<button type="submit" className="btn btn-primary mr-1">Search</button>
<button type="button" onClick={() => resetFunction()} className="btn btn-secondary">Clear</button>
</div>
</div>
</form>
</div>
<div className="card-body">
<p className="card-header">Search results: </p>
{userSearchResults}
{ <ul>
{ searchResults.map( result => {
const {id, name, image} = result;
return (
<li key={id} className='card'>
<h3>{name}</h3>
</li>
)
} ) }
</ul> }
</div>
</div>
);
}
Please correct me. Highly appreciated if suggest me with best practices.
Thank you!

I will assume the data returned from your API is an array of objects, please try this and let me know if that works:
export default function Home() {
const [userSearchResults, setUserSearchResults] = useState([]);
const validationSchema = Yup.object().shape({
searchQuery: Yup.string().required("This field is required"),
});
const formOptions = { resolver: yupResolver(validationSchema) };
const { errors } = formState;
const resetFunction = () => {
setUserSearchResults([]);
};
const onSubmitFunction = async (event) => {
console.log("search query =====> ", event.searchQuery);
const userEndPoint = "/api/users/";
const response = await fetch(userEndPoint + event.searchQuery);
const data = await response.json();
setUserSearchResults(data.results);
};
return (
<div className="m-3 card">
<h5 className="card-header">Example App</h5>
<div className="card-body">
<form onSubmit={handleSubmit(onSubmitFunction)}>
<div className="form-row row">
<div className="col-6 d-flex align-items-center">
<input
name="searchQuery"
type="text"
{...register("searchQuery")}
className={`form-control ${
errors.searchQuery ? "is-invalid" : ""
}`}
/>
<div className="invalid-feedback">
{errors.searchQuery?.message}
</div>
</div>
<div className="col-6">
<button type="submit" className="mr-1 btn btn-primary">
Search
</button>
<button
type="button"
onClick={() => resetFunction()}
className="btn btn-secondary"
>
Clear
</button>
</div>
</div>
</form>
</div>
<div className="card-body">
<p className="card-header">Search results: </p>
<ul>
{userSearchResults.length > 0 && userSearchResults.map((result) => {
const { id, name, image } = result;
return (
<li key={id} className="card">
<h3>{name}</h3>
</li>
);
})}
</ul>
</div>
</div>
);
}

Related

How can I maintain the order of adding items in react web app?

How can I create an order of adding items. I should be able to add one after the other item during on click. By default it should display the Textarea first and then blockquote ( see below )
a) When a user click on Text area button, it should add one after the blockquote.
b) Then when the user clicks on Code area button, it should add after Textarea. Could someone please advise ?
CSB link: https://codesandbox.io/s/distracted-worker-26jztf?file=/src/App.js
Something similar >> Expected behaviour: https://jsfiddle.net/nve8qdbu/8/
import "./styles.css";
import React, { useState, useEffect } from "react";
import { useNavigate } from "react-router-dom";
import { useForm } from "react-hook-form";
const blogListData = [
{
id: 1,
heading: "React state",
date: "22-May-2022",
tag: "React",
count: "3"
},
{
id: 2,
heading: "Cypress testing detailss",
date: "22-May-2022",
tag: "Cypress",
count: "5"
}
];
const Admin = () => {
const [createImageTag, setImageTag] = useState("");
const [fields, setFields] = useState([{ value: null }]);
const [createCode, setCreateCode] = useState([{ value: null }]);
const [blogList, setBlogList] = useState([]);
const {
register,
handleSubmit,
formState: { errors },
reset
} = useForm();
useEffect(() => {
setBlogList(blogListData);
}, []);
function handleChangeTextArea(i, event) {
const values = [...fields];
values[i].value = event.target.value;
setFields(values);
}
function handleChangeCode(i, event) {
const codeValues = [...createCode];
codeValues[i].value = event.currentTarget.innerText;
setCreateCode(codeValues);
}
function handleTextAreaAdd() {
const values = [...fields];
values.push({ value: null });
setFields(values);
}
function handleCodeAreaAdd() {
const codeValues = [...createCode];
codeValues.push({ value: null });
setCreateCode(codeValues);
}
function handleImageAreaAdd() {
const image = [...createImageTag];
image.push({ value: null });
setCreateCode(image);
}
function handleRemoveText(i) {
const values = [...fields];
values.splice(i, 1);
setFields(values);
}
function handleRemoveCode(i) {
const codeValues = [...createCode];
codeValues.splice(i, 1);
setCreateCode(codeValues);
}
const handleLogout = () => {
localStorage.removeItem("loginEmail");
};
return (
<div id="App">
<div className="parent">
<div className="adminSection">
<h1>Create a new blog</h1>
<div className="row">
<div className="logout">
<img
src="/images/logout.png"
alt="Logout"
onClick={handleLogout}
></img>
</div>
<div className="createBlogSection">
<div className="row">
<button
onClick={() => handleTextAreaAdd()}
className="textAreaBtn"
>
Text Area
</button>
<button
onClick={() => handleCodeAreaAdd()}
className="codeAreaBtn"
>
Code Area
</button>
<button
onClick={() => handleImageAreaAdd()}
className="imageAreaBtn"
>
Add Image
</button>
</div>{" "}
<br></br>
<div className="row">
{fields.map((field, idx) => {
return (
<div key={`${field}-${idx}`} className="dtextArea">
<button
type="button"
onClick={() => handleRemoveText(idx)}
className="closeElement"
>
X
</button>
<textarea
type="text"
id="blogtext"
placeholder="Enter your text here"
className="defaultTextArea"
{...register("blogtext", {
required: true,
minLength: {
value: 25,
message: "Minimum length of 25 letters"
}
})}
value={field.value || ""}
onChange={(e) => handleChangeTextArea(idx, e)}
/>
<span className="validationmsg">
{errors.blogtext &&
errors.blogtext.type === "required" && (
<span>Blog text is required !</span>
)}
{errors.blogtext && (
<span>{errors.blogtext.message}</span>
)}
</span>
</div>
);
})}
</div>
<div className="row">
{createCode.map((code, idx) => {
return (
<div key={`${code}-${idx}`} className="dCodeArea">
<button
type="button"
onClick={() => handleRemoveCode(idx)}
className="closeElement"
>
X
</button>
<blockquote
type="text"
id="blogCode"
contentEditable="true"
className="codehighlight"
placeholder="Enter your code here"
{...register("blogCode", {
required: true
})}
value={code.value || ""}
onInput={(e) => handleChangeCode(idx, e)}
/>
</div>
);
})}
</div>
<div className="row">
</div>
<div className="row">
<div className="submitSection">
<input type="submit" className="submitBtn" />
</div>
</div>
</div>
</div>
</div>
<div className="blogListSection">
<h1>Edit blogs</h1>
<div className="row">
<div className="editBlogSection">
{blogList.map(({ id, heading, count }) => (
<a
key={id}
href="https://www.testingsite.com/"
className="blogitems"
>
<pre>
<span>{count}</span> {heading}
</pre>
</a>
))}
</div>
</div>
</div>
</div>
</div>
);
};
export default Admin;
react is designed for components . each of your list elements should be refactored by a component.then it would be easier. i think a single react component could do the trick

i can try select drop-down option value but every time get last value

I can add select box in loop with one of input box and i want to get every value of select option with input value. right now i am get only last value of select option and also last value of input box. but can get each and every value of select option and input ans. any one help me what is wrong in this code. thanks
here is my code...
export default function AccountRecoveryModal(props) {
const divStyle = {
display: props.displayModal ? 'block' : 'none'
};
function closeModal(e) {
e.stopPropagation()
props.closeModal = false;
}
const [select, setSelected] = useState('');
const [question, setQuestion] = useState([]);
const [ans, setAns] = useState([]);
const [optionList,setOptionList] = useState([]);
const [userinfo, setUserInfo] = useState({
question: [],
answer: [],
});
const fetchData = () => {
axios
.get(Recovery_Questions_URL)
.then((response) => {
const { data } = response;
if(response.status === 200){
//check the api call is success by stats code 200,201 ...etc
setOptionList(data.data)
}else{
//error handle section
}
})
.catch((error) => console.log(error));
};
const [sampleArray, setSampleArray] = useState([])
let temp = [];
const setQueAns = (e, type) => {
console.log(e)
temp.push({key:type,value:e});
const ary = [...temp,{key:type,value:e}]
setQuestion({key:type,value:e})
setQuestion( [...temp, ary])
const listItems = ary.map((temps) =>
<>{temps.value}</>
);
console.log(question);
}
const keys = question.key;
const setData = () => {
axios
.post(Recovery_Ans_URL, {
user_id: props.userId,
[keys] : question.value
})
.then((response) => {
const {data} = response;
console.log(response)
if (response.status === 200) {
if (response.data != null) {
alert('done');
} else {
alert(response.data.message);
}
} else {
//error handle section
}
})
.catch((error) => console.log(error));
};
useEffect(()=>{
fetchData();
},[])
const initialValues = {
optionList
};
return (
<>
<div className="modal" id="accountRecovery" style={divStyle}>
<div className="modal-dialog modal-dialog-centered">
<div className="modal-content">
<div className="modal-header row mx-0 border-0 shadow-none">
<div className="col-md-12 d-flex">
{/*<img src="assets/images/icon/layer1.svg" alt="" className="pe-2"*/}
{/* style="width: 30px;" /> */}
<h4 className="modal-title text-white">Account Recovery</h4>
</div>
</div>
<div className="modal-body row mx-0">
<form className="py-0">
{optionList.map((item) => (
<>
<select className="form-select fill border-0 shadow-none font-13 py-2 my-3"
aria-label="Default select example" onChange={(e) => setQueAns(e.currentTarget.value, "recovery_question_"+`${item.question_id}`)}>
<option selected>Select Question</option>
<option key={item.question_id} name={"recovery_question_"+`${item.question_id}`} value={item.question_id} >
{item.question}
</option>
</select>
<div className="col mt-3 form-float btn-add">
<input type="text"
className="form-control fill border-0 shadow-none font-13 py-2 my-3"
placeholder="Your Answer" name={"recovery_answer_"+`${item.question_id}`} onChange={(e) => setQueAns(e.currentTarget.value, "recovery_answer_"+`${item.question_id}`)} />
<label className="floating-label font-13 text-white">Your Answer</label>
</div>
</>
)
)}
</form>
</div>
<div className="modal-footer border-0 mx-0">
<div className="row w-100">
<div className="col-md-6 my-1">
<a className="login-btn btn-hover color-1" href="#" data-bs-target="#important"
data-bs-toggle="modal" onClick={setData}>Next</a>
</div>
</div>
</div>
</div>
</div>
<button type="button" className="btn-close rounded-circle opacity-100"
data-bs-dismiss="modal"></button>
</div>
</>
);
}
```[enter image description here](https://i.stack.imgur.com/JIlEw.png)

React error "Can't perform a React state update on an unmounted component. This is a no-op, but it indicates a memory leak"

I have a Login component and I receive that error: Can't perform a React state update on an unmounted component. This is a no-op, but it indicates a memory leak. I googled for the error and found some people having the same issue and I tried to solve it like them, but it didn't work for me. Why I have this error, and how do I fix it? Thanks
COMPONENT LOGIN
import React, { useState, useContext, useEffect } from "react";
import { useLocation } from "wouter";
import logic from "../../logic";
import { AuthContext } from "../../context/AuthContext";
import validate from "./validateRulesLogin";
import literals from "../../common/i18n/literals";
import "./index.css";
export default function Login(language) {
const [, setAuth] = useContext(AuthContext);
const [, pushLocation] = useLocation();
const [messageError, setMessageError] = useState("");
const [errorsValidateForm, setErrorsValidateForm] = useState({});
const [isSubmitting, setIsSubmitting] = useState(false);
const [data, setData] = useState({ email: "", password: "" });
const { lang } = language;
const { login_notRegister } = literals;
useEffect(() => {}, [errorsValidateForm, isSubmitting]);
let isCancelled = false;
async function handleOnSubmit(e) {
e.preventDefault();
if (!isSubmitting) {
let errorsForm = validate(data, lang);
if (Object.keys(errorsForm).length === 0 && !isCancelled) {
setIsSubmitting(true);
const { email, password } = data;
try {
await logic.loginUser(email, password, lang);
setAuth(true);
setIsSubmitting(false);
pushLocation("/");
} catch (error) {
setMessageError(error.message);
setIsSubmitting(false);
setTimeout(() => {
setMessageError("");
}, 3000);
}
}
setErrorsValidateForm(errorsForm);
}
return () => {
isCancelled = true;
};
}
const handleOnChangeData = (e) => {
e.preventDefault();
setData({
...data,
[e.target.name]: e.target.value,
});
};
return (
<>
{messageError && (
<div className="message">
<p className="messageError">{messageError}</p>
</div>
)}
<section className="hero is-fullwidth">
<div className="hero-body">
<div className="container">
<div className="columns is-centered">
<div className="column is-4">
<form id="form" onSubmit={(e) => handleOnSubmit(e)} noValidate>
<div className="field">
<p className="control has-icons-left">
<input
className="input"
name="email"
type="email"
placeholder="Email"
onChange={handleOnChangeData}
required
/>
<span className="icon is-small is-left">
<i className="fas fa-envelope"></i>
</span>
</p>
{errorsValidateForm.email && (
<p className="help is-danger">
{errorsValidateForm.email}
</p>
)}
</div>
<div className="field">
<p className="control has-icons-left">
<input
className="input"
name="password"
type="password"
placeholder="Password"
onChange={handleOnChangeData}
required
/>
<span className="icon is-small is-left">
<i className="fas fa-lock"></i>
</span>
</p>
{errorsValidateForm.password && (
<p className="help is-danger">
{errorsValidateForm.password}
</p>
)}
</div>
<div className="field">
<p className="control">
<button type="submit" className="button is-success">
Login
</button>
</p>
</div>
<div>
{login_notRegister[lang]}
</div>
</form>
</div>
</div>
</div>
</div>
</section>
</>
);
}

How do i limit the list of data being rendered for a particular list in react js

I'm trying to create an app that when the user clicks on create button a survey question with four answers gets created. The goal is that in a single list the user can maximum add up to 4 questions and a minimum of 1 question. So when the user tries to add another question after the 4th question a new survey list should be created. So one survey list can contain a maximum of four questions.
//Survey.js
import React, { useState, useEffect } from "react";
import { Fragment } from "react";
import "./Survey.css";
import CreateSurvey from "../modals/CreateSurvey";
import Card from "../card/Card";
const Survey = () => {
const [modal, setModal] = useState(false);
const [surveyList, setSurveyList] = useState([]);
useEffect(() => {
let arr = localStorage.getItem("surveyList");
if (arr) {
let obj = JSON.parse(arr);
setSurveyList(obj);
}
}, []);
// const surveyListArray = [];
// while (surveyList.length > 0) {
// surveyListArray.push(surveyList.splice(0, 3));
// }
const deleteSurvey = (index) => {
let tempList = surveyList;
tempList.splice(index, 1);
localStorage.setItem("surveyList", JSON.stringify(tempList));
setSurveyList(tempList);
window.location.reload();
};
const toggle = () => {
setModal(!modal);
};
const updateListArray = (obj, index) => {
let tempList = surveyList;
tempList[index] = obj;
localStorage.setItem("surveyList", JSON.stringify(tempList));
setSurveyList(tempList);
window.location.reload();
};
const saveSurvey = (surveyObj) => {
let tempList = surveyList;
tempList.push(surveyObj);
localStorage.setItem("surveyList", JSON.stringify(tempList));
setSurveyList(surveyList);
setModal(false);
};
return (
<Fragment>
<div className="header text-center">
<h5>Survey</h5>
<button className="btn btn-primary" onClick={() => setModal(true)}>
Create Survey
</button>
</div>
<div className="survey-container">
{surveyList &&
surveyList.map((obj, index) => (
<Card
surveyObj={obj}
index={index}
deleteSurvey={deleteSurvey}
updateListArray={updateListArray}
>
<input type="radio" name="answerOne" />
</Card>
))}
</div>
<CreateSurvey toggle={toggle} modal={modal} save={saveSurvey} />
</Fragment>
);
};
export default Survey;
//Card.js
import React, { useState } from "react";
import "./Card.css";
import EditSurvey from "../modals/EditSurvey";
const Card = ({ surveyObj, deleteSurvey, index, updateListArray }) => {
const [modal, setModal] = useState(false);
const toggle = () => {
setModal(!modal);
};
const updateSurvey = (obj) => {
updateListArray(obj, index);
};
const deleteHandler = () => {
deleteSurvey(index);
};
return (
<div>
<div className="card-wrapper mr-5">
<div className="card-top"></div>
<div className="survey-holder">
<span className="card-headers">{surveyObj.name}</span>
<span className="check">
<input type="radio" className="radio" />
<p className="answer"> {surveyObj.answerOne}</p>
</span>
<span className="check">
<input type="radio" className="radio" />
<p className="answer"> {surveyObj.answerTwo}</p>
</span>
<span className="check">
<input type="radio" className="radio" />
<p className="answer"> {surveyObj.answerThree}</p>
</span>
<span className="check">
<input type="radio" className="radio" />
<p className="answer"> {surveyObj.answerFour}</p>
</span>
<div className="icons">
<i className="far fa-edit edit" onClick={() => setModal(true)}></i>
<i className="fas fa-trash-alt delete" onClick={deleteHandler}></i>
</div>
</div>
<EditSurvey
modal={modal}
toggle={toggle}
updateSurvey={updateSurvey}
surveyObj={surveyObj}
/>
</div>
</div>
);
};
export default Card;
//CreateSurvey.js
import React, { useState } from "react";
import { Button, Modal, ModalHeader, ModalBody, ModalFooter } from "reactstrap";
import { Fragment } from "react";
const CreateSurvey = ({ modal, toggle, save }) => {
const [question, setQuestion] = useState("");
const [answerOne, setAnswerOne] = useState("");
const [answerTwo, setAnswerTwo] = useState("");
const [answerThree, setAnswerThree] = useState("");
const [answerFour, setAnswerFour] = useState("");
const changeHandler = (e) => {
const { name, value } = e.target;
if (name === "question") {
setQuestion(value);
} else if (name === "answerOne") {
setAnswerOne(value);
} else if (name === "answerTwo") {
setAnswerTwo(value);
} else if (name === "answerThree") {
setAnswerThree(value);
} else {
setAnswerFour(value);
}
};
const saveHandler = (e) => {
e.preventDefault();
let surveyObj = {};
surveyObj["name"] = question;
surveyObj["answerOne"] = answerOne;
surveyObj["answerTwo"] = answerTwo;
surveyObj["answerThree"] = answerThree;
surveyObj["answerFour"] = answerFour;
save(surveyObj);
};
return (
<Fragment>
<Modal isOpen={modal} toggle={toggle}>
<ModalHeader toggle={toggle}>Create a Survey Question</ModalHeader>
<ModalBody>
<form>
<div>
<div className="form-group">
<label>Survey Questions</label>
<input
type="text"
className="form-control"
value={question}
name="question"
onChange={changeHandler}
/>
</div>
</div>
<div className="mt-2">
<label>Survey Answers</label>
<div className="form-group">
<label>Answer 1</label>
<input
type="text"
className="form-control mt-2 mb-2"
value={answerOne}
name="answerOne"
onChange={changeHandler}
/>
</div>
<div className="form-group">
<label>Answer 2</label>
<input
type="text"
className="form-control mt-2 mb-2"
value={answerTwo}
name="answerTwo"
onChange={changeHandler}
/>
</div>
<div className="form-group">
<label>Answer 3</label>
<input
type="text"
className="form-control mt-2 mb-2"
value={answerThree}
name="answerThree"
onChange={changeHandler}
/>
</div>
<div className="form-group">
<label>Answer 4</label>
<input
type="text"
className="form-control mt-2 mb-2"
value={answerFour}
name="answerFour"
onChange={changeHandler}
/>
</div>
</div>
</form>
</ModalBody>
<ModalFooter>
<Button color="primary" onClick={saveHandler}>
Create
</Button>
<Button color="secondary" onClick={toggle}>
Cancel
</Button>
</ModalFooter>
</Modal>
</Fragment>
);
};
export default CreateSurvey;

React.JS TypeError: Cannot read property 'value' of undefined

Having an issue with a react form and I can't figure it out. I am getting TypeError: Cannot read property 'value' of undefined when submitting. The issue started when I added "location" to the form. Not sure how this is causing it to break as I am just adding another item to the form. I have attempted to fix any typos, and when I take out the "location" it submits with no issue.
import React from "react";
import Firebase from "firebase";
import config from "./config";
class App extends React.Component {
constructor(props) {
super(props);
Firebase.initializeApp(config);
this.state = {
pallets: []
};
}
componentDidMount() {
this.getUserData();
}
componentDidUpdate(prevProps, prevState) {
if (prevState !== this.state) {
this.writeUserData();
}
}
writeUserData = () => {
Firebase.database()
.ref("/")
.set(this.state);
console.log("DATA SAVED");
};
getUserData = () => {
let ref = Firebase.database().ref("/");
ref.on("value", snapshot => {
const state = snapshot.val();
this.setState(state);
});
};
handleSubmit = event => {
event.preventDefault();
let name = this.refs.name.value;
let QTY = this.refs.QTY.value;
let uid = this.refs.uid.value;
let location = this.refs.location.value;
if (uid && name && QTY && location) {
const { pallets } = this.state;
const devIndex = pallets.findIndex(data => {
return data.uid === uid;
});
pallets[devIndex].name = name;
pallets[devIndex].QTY = QTY;
pallets[devIndex].location = location;
this.setState({ pallets });
} else if (name && QTY && location) {
const uid = new Date().getTime().toString();
const { pallets } = this.state;
pallets.push({ uid, name, QTY, location });
this.setState({ pallets });
}
this.refs.name.value = "";
this.refs.QTY.value = "";
this.refs.uid.value = "";
this.refs.location.value = "";
};
removeData = pallet => {
const { pallets } = this.state;
const newState = pallets.filter(data => {
return data.uid !== pallet.uid;
});
this.setState({ pallets: newState });
};
updateData = pallet => {
this.refs.uid.value = pallet.uid;
this.refs.name.value = pallet.name;
this.refs.QTY.value = pallet.QTY;
this.refs.location.value =pallet.location;
};
render() {
const { pallets } = this.state;
return (
<React.Fragment>
<div className="container">
<div className="row">
<div className="col-xl-12">
<h1>Creating Pallet App</h1>
</div>
</div>
<div className="row">
<div className="col-xl-12">
{pallets.map(pallet => (
<div
key={pallet.uid}
className="card float-left"
style={{ width: "18rem", marginRight: "1rem" }}
>
<div className="card-body">
<h5 className="card-title">{pallet.name}</h5>
<p className="card-text">{pallet.QTY}</p>
<p className="card-text">{pallet.location}</p>
<button
onClick={() => this.removeData(pallet)}
className="btn btn-link"
>
Delete
</button>
<button
onClick={() => this.updateData(pallet)}
className="btn btn-link"
>
Edit
</button>
</div>
</div>
))}
</div>
</div>
<div className="row">
<div className="col-xl-12">
<h1>Add new pallet here</h1>
<form onSubmit={this.handleSubmit}>
<div className="form-row">
<input type="hidden" ref="uid" />
<div className="form-group col-md-6">
<label>Name</label>
<input
type="text"
ref="name"
className="form-control"
placeholder="Name"
/>
</div>
<div className="form-group col-md-6">
<label>QTY</label>
<input
type="text"
ref="QTY"
className="form-control"
placeholder="QTY"
/>
</div>
<div className="form-group col-md-6">
<label>Location</label>
<input
type="text"
ref="QTY"
className="form-control"
placeholder="Location"
/>
</div>
</div>
<button type="submit" className="btn btn-primary">
Save
</button>
</form>
</div>
</div>
</div>
</React.Fragment>
);
}
}
export default App;
You haven't created a ref named location
Change:
<input
type="text"
ref="QTY"
className="form-control"
placeholder="Location"
/>
to:
<input
type="text"
ref="location"
className="form-control"
placeholder="Location"
/>

Resources