How can I pass a variable between two components in React? - javascript

I have a form component in React that I use to send data to a pg database.
This is my form script :
import bodyParser from 'body-parser';
import React, { Fragment, useState } from 'react';
import RatingStar from '../components/rating'
const InputData = () => {
const [name, setName] = useState('')
const [rating, setRating] = useState('')
const onSubmitForm = async(e) => {
e.preventDefault();
try {
const payload = {
name,
rating
}
const response = await fetch("path", {
method:"POST",
headers:{"Content-Type":"application/json"},
body:JSON.stringify(payload)
});
window.location = "/";
} catch (error) {
console.log(error.message);
}
}
return(
<Fragment>
<div className="container">
<h1 className="text-center mt-5">RATE</h1>
<form className="mt-5" onSubmit={onSubmitForm}>
<div className="form-group">
<input
placeholder="Name"
type='text'
className='form-control'
value={name}
onChange={e => setName(e.target.value)}
/>
</div>
<div className="form-group">
<div>
<RatingStar
value={}
/>
</div>
</div>
<div className="d-flex justify-content-center">
<button type="submit" className="d-flex btn btn-primary">Submit</button>
</div>
</form>
</div>
</Fragment>
);
}
export default InputData;
And this is my rating component :
import React, { useState } from 'react';
import { render } from 'react-dom';
import ReactStars from 'react-rating-stars-component'
import './style.css'
export default function RatingStar() {
const [rating, setRating] = useState("")
const secondExample = {
size: 50,
count: 5,
color: "black",
activeColor: "yellow",
value: 0,
a11y: true,
isHalf: true,
emptyIcon: <i className="far fa-star" />,
halfIcon: <i className="fa fa-star-half-alt" />,
filledIcon: <i className="fa fa-star" />,
onChange: (newValue) => {
console.log(`Example 2: new value is ${newValue}`);
setRating(newValue) // my try
}
};
return (
<div className="starComponent">
<ReactStars {...secondExample}
/>
</div>
);
}
So I was wondering how I could use newValue in the form component.
For now I tried using useState in the rating component but I can't access it from the form component to use it in my paylod.

Instead of keeping same state (i.e rating value) in two components, keep it in form component and pass it as prop to the Rating component.
Rating component will notify the parent(Form) component whenever the value gets changed by calling a function. This is called Lifting state up.
Here is the code for Rating component which gets rating and onRatingChange props from the form component. onRatingChange will be called with newValue from inside onChange function.
export default function RatingStar({ rating, onRatingChange }) {
const secondExample = {
size: 50,
count: 5,
color: "black",
activeColor: "yellow",
value: rating, // pass rating value here
a11y: true,
isHalf: true,
emptyIcon: <i className="far fa-star" />,
halfIcon: <i className="fa fa-star-half-alt" />,
filledIcon: <i className="fa fa-star" />,
onChange: (newValue) => {
console.log(`Example 2: new value is ${newValue}`);
// call onRatingChange function with new rating value
onRatingChange(newValue);
}
};
return (
<div className="starComponent">
<ReactStars {...secondExample} />
</div>
);
}
This is the code for Form component.
const InputData = () => {
const [name, setName] = useState('')
const [rating, setRating] = useState(0)
const onSubmitForm = async(e) => {
e.preventDefault();
try {
const payload = {
name,
rating
}
const response = await fetch("path", {
method:"POST",
headers:{"Content-Type":"application/json"},
body:JSON.stringify(payload)
});
window.location = "/";
} catch (error) {
console.log(error.message);
}
}
return(
<Fragment>
<div className="container">
<h1 className="text-center mt-5">RATE</h1>
<form className="mt-5" onSubmit={onSubmitForm}>
<div className="form-group">
<input
placeholder="Name"
type='text'
className='form-control'
value={name}
onChange={e => setName(e.target.value)}
/>
</div>
<div className="form-group">
<div>
<RatingStar
rating={rating}
onRatingChange={(newRating)=>{
// update rating value here when you get a new value
setRating(newRating);
}}
/>
</div>
</div>
<div className="d-flex justify-content-center">
<button type="submit" className="d-flex btn btn-primary">Submit</button>
</div>
</form>
</div>
</Fragment>
);
}
export default InputData;

You need to keep the state in InputData and pass it into RatingStar with the change handler.
const InputData = () => {
const [rating, setRating] = useState(0);
const handleRatingChange = (newRating) => {
console.log(`setting rating to ${newRating}`);
setRating(newRating);
}
return (
<RatingStar value={rating} onChange={handleRatingChange} />
);
};
Then RatingStar just uses the values from its parent.
const RatingStar = ({ value, onChange }) => {
const otherProps = {};
return (
<ReactStars {...otherProps} value={value} onChange={onChange} />
);
};
Here, RatingStar is a controlled component

Related

React - Elements not rendering properly

I'm making a note taking app. I have an array set to state that holds the notes and each note is set to state as an object. My NoteList component maps over the array to render a new Note component when the save button is pressed. Everything works so far, except for the first note. When the first note is saved, the delete button renders but not the user input or date. On every subsequent save, everything renders how it should. I've looked over my code but I'm not sure what is causing this. Can someone please point me in the right direction?
import { useState } from 'react';
import uniqid from 'uniqid';
import NoteList from './components/NoteList';
function App() {
const [note, setNote] = useState({
note: '',
date: '',
id: ''
})
const [notes, setNotes] = useState([])
const [error, setError] = useState(false);
function handleAddNote(text) {
const date = new Date();
const newNote = {
text: text,
date: date.toLocaleDateString(),
id: uniqid()
}
setNote(newNote);
const newNotes = [
...notes,
note
]
setNotes(newNotes);
}
return (
<div className="App">
<h1>My Notes</h1>
<input placeholder='Type to search...'></input>
<NoteList notes={notes} handleAddNote={handleAddNote}/>
</div>
);
}
export default App;
import Note from './Note'
import AddNote from './AddNote'
function NoteList({ notes, handleAddNote }) {
return (
<div className='list-container'>
{notes.map((note) => (
<Note text={note.text} id={note.id} date={note.date}
key={note.id} notes={notes} note={note}/>
))}
<AddNote handleAddNote={handleAddNote}/>
</div>
)
}
export default NoteList;
function Note({ note }) {
return (
<div className='note-container'>
<span className='note-text'>{note.text}</span>
<div className='note-footer'>
<p className='note-date'>{note.date}</p>
<button>Delete</button>
</div>
</div>
)
}
export default Note;
import { useState } from 'react';
function AddNote({ handleAddNote } ) {
const [noteText, setNoteText] = useState('');
function handleChange(e) {
setNoteText(e.target.value);
}
function handleSaveNote() {
if (noteText) {
handleAddNote(noteText);
setNoteText('');
}
}
return (
<div className='new-note-container'>
<textarea onChange={handleChange} value={noteText}
rows='5' cols='30' placeholder='Type to enter a note...'
</textarea>
<div className='count-container'>
<p>Character Count</p>
<button onClick={handleSaveNote}>Save</button>
</div>
</div>
)
}
export default AddNote;
I think that the thing you are missing is that after calling setNote it does not change note on the current render. Only in the next render for that component note will get the new state.
In your case I don't see way you need to have a state for the new note so you can change your App component to be something like this:
function App() {
const [notes, setNotes] = useState([])
const [error, setError] = useState(false);
function handleAddNote(text) {
const date = new Date();
const newNote = {
text: text,
date: date.toLocaleDateString(),
id: uniqid()
}
setNotes((prevNotes) => [...prevNotes, newNote]);
}
return (
<div className="App">
<h1>My Notes</h1>
<input placeholder='Type to search...'></input>
<NoteList notes={notes} handleAddNote={handleAddNote}/>
</div>
);
}
All of these functions, such as adding notes, deleting notes, and searching for notes, are implemented in this code and work properly. I think this might be helpful for you!
import { useState } from "react";
import { uuid } from "uuidv4";
const SelectChip = () => {
const [notes, setNotes] = useState([]);
const [searchTerm, setSearchTerm] = useState("");
function handleAddNote(text) {
const date = new Date();
setNotes((prev) => [
...prev,
{
text: text,
date: date.toLocaleDateString(),
id: uuid()
}
]);
}
return (
<div className="App">
<h1>My Notes</h1>
<input
value={searchTerm}
onChange={(event) => setSearchTerm(event.target.value)}
placeholder="Type to search..."
/>
<NoteList
notes={notes}
setNotes={setNotes}
handleAddNote={handleAddNote}
search={searchTerm}
/>
</div>
);
};
export default SelectChip;
function NoteList({ notes, setNotes, handleAddNote, search }) {
const filteredItems = notes.filter((item) =>
item.text.toLowerCase().includes(search.toLowerCase())
);
return (
<div className="list-container">
{filteredItems.map((note) => {
return (
<Note
text={note.text}
id={note.id}
date={note.date}
key={note.id}
setNotes={setNotes}
note={note}
/>
);
})}
<AddNote handleAddNote={handleAddNote} />
</div>
);
}
function Note({ note, setNotes }) {
function handleDelete(noteId) {
setNotes((prev) => prev.filter((note) => note.id !== noteId));
}
return (
<div className="note-container">
<span className="note-text">{note.text}</span>
<div className="note-footer">
<p className="note-date">{note.date}</p>
<button onClick={() => handleDelete(note.id)}>Delete</button>
</div>
</div>
);
}
function AddNote({ handleAddNote }) {
const [noteText, setNoteText] = useState("");
function handleChange(e) {
setNoteText(e.target.value);
}
function handleSaveNote() {
if (noteText) {
handleAddNote(noteText);
setNoteText("");
}
}
return (
<div className="new-note-container">
<textarea
onChange={handleChange}
value={noteText}
rows="5"
cols="30"
placeholder="Type to enter a note..."
></textarea>
<div className="count-container">
<p>Character Count</p>
<button onClick={handleSaveNote}>Save</button>
</div>
</div>
);
}

I need to re render state and make onChange operator work on input element

I am trying to edit the input box in a table in a CRUD manner ,but I am unable to update the state and make the input box read-writable.
I am using redux-toolkit to dispatch action for fetching the employee list from json-server.
In the middleware redux-saga is used.
The link to git hub repo:https://github.com/grbknr1996/employee-manager
import React, { useEffect, useState } from "react";
import "./Home.scss";
import { useDispatch, useSelector } from "react-redux";
import { sagaActions } from "../redux/sagaActions";
import { AiOutlineDelete, AiOutlineEdit } from "react-icons/ai";
import { MdDone } from "react-icons/md";
import { FormikBag, useFormik } from "formik";
const Home: React.FC = () => {
const dispatch = useDispatch();
const employees = useSelector((state: any) => state.employees.employees);
const [edit, setEdit] = useState({ edit: false, id: null as any });
const [editInfo, setEditInfo] = useState(employees);
const initialValues = {
id: "",
name: "",
designation: "",
address: "",
};
const formik = useFormik({
initialValues: initialValues,
onSubmit: (values) => {
console.log(JSON.stringify(values, null, 2));
},
});
useEffect(() => {
dispatch({ type: sagaActions.FETCH_EMPLOYEES_SAGA });
}, []);
useEffect(() => {
setInfo();
}, [employees]);
const setInfo = () => setEditInfo(employees);
const handleEdit = (e: React.MouseEvent, index: number) => {
console.log(index);
setEdit({ edit: true, id: index });
};
const handleDelete = (e: React.MouseEvent, index: number) => {
dispatch({ type: sagaActions.DELETE_EMPLOYEE_SAGA, id: index });
};
const toggleEdit = (e: React.FormEvent) => {
console.log("edit toggle");
setEdit({ edit: false, id: null as any });
};
const handleEditChange = (e: any, index: number) => {
setEditInfo(
employees.map((emp: any) =>
emp.id === index ? (emp.name = e.target.value) : emp
)
);
};
return (
<div className="main-container">
<div className="table-container">
<div className="table-row heading">
<div className="row-item">ID</div>
<div className="row-item">NAME</div>
<div className="row-item">DESIGNATION</div>
<div className="row-item">ADDRESS</div>
<div className="row-item">ACTIONS</div>
</div>
{editInfo.map((emp: any, index: number) =>
edit.edit && edit.id === index ? (
<>
<form>
<div className="table-row">
<div className="row-item" key={emp.id}>
{emp.id}
</div>
<input
className="row-item"
name="name"
value={emp.name}
onChange={(e) => handleEditChange(e, index)}
/>
<input className="row-item" value={emp.designation} />
<input className="row-item" value={emp.address} />
<div className="row-item">
<button type="submit">
<MdDone
className="changeColor done"
onClick={(e) => toggleEdit(e)}
/>
</button>
</div>
</div>
</form>
</>
) : (
<div className="table-row">
<div className="row-item" key={emp.id}>
{emp.id}
</div>
<div className="row-item" key={emp.name}>
{emp.name}
</div>
<div className="row-item" key={emp.designation}>
{emp.designation}
</div>
<div className="row-item" key={emp.address}>
{emp.address}
</div>
<div className="row-item">
<AiOutlineEdit
className="changeColor edit"
onClick={(e) => handleEdit(e, index)}
/>
<AiOutlineDelete
className="changeColor delete"
onClick={(e) => handleDelete(e, emp.id)}
/>
</div>
</div>
)
)}
</div>
</div>
);
};
export default Home;
Any will help will be great .Thanks in advance :) .
Instead of value for the input, use defaultValue
<input className="row-item" name="name" defaultValue={emp.name} onChange={(e)=> handleEditChange(e, index)} />

React dynamic form input

I have a React form with dynamic input fields that a user can add and remove input fields. When i submit the form, i log the values from each input in an array. The problem is that i can't type continuously in a input. When i type in input, i can type only one character and it focus out. How can i fix it?
CodeSandbox
App.js
import React, { useState } from "react";
import ReactDOM from "react-dom";
import "./styles.css";
function App() {
const [fields, setFields] = useState([""]);
function handleChange(i, event) {
const values = [...fields];
values[i] = event.target.value;
setFields(values);
}
function handleAdd() {
const values = [...fields];
values.push("");
setFields(values);
}
function handleRemove(i) {
const values = [...fields];
values.splice(i, 1);
setFields(values);
}
function submitHandler(event) {
event.preventDefault();
console.log(fields);
}
return (
<div className="App">
<h1>Hello CodeSandbox</h1>
<form onSubmit={submitHandler}>
<button type="button" onClick={() => handleAdd()}>
Add Input
</button>
{fields.map((field, idx) => {
return (
<div key={`${field}-${idx}`}>
<input
type="text"
placeholder="Enter text"
value={field || ""}
onChange={(e) => handleChange(idx, e)}
/>
<button type="button" onClick={() => handleRemove(idx)}>
X
</button>
</div>
);
})}
<button className="margin-top" type="submit">
Submit
</button>
</form>
</div>
);
}
export default App;
Replace your code with this
<div key={`${"asdf"}-${idx}`}>
<input
type="text"
placeholder="Enter text"
value={field || ""}
onChange={(e) => handleChange(idx, e)}
/>
<button type="button" onClick={() => handleRemove(idx)}>
X
</button>
</div>
i have used a third party debounce , you can choose anything you want
code
import React, { useState } from "react";
import AwesomeDebouncePromise from "awesome-debounce-promise";
import ReactDOM from "react-dom";
import "./styles.css";
function App() {
const [fields, setFields] = useState([""]);
function handleChange(i, event) {
const values = [...fields];
values[i] = event.target.value;
setFields(values);
}
function handleAdd() {
const values = [...fields];
values.push("");
setFields(values);
}
function handleRemove(i) {
const values = [...fields];
values.splice(i, 1);
setFields(values);
}
const searchAPIDebounced = AwesomeDebouncePromise((event) => {
console.log(fields);
}, 100);
const submitHandler = async (event) => {
event.preventDefault();
const result = await searchAPIDebounced(event);
};
return (
<div className="App">
<h1>Hello CodeSandbox</h1>
<form onSubmit={submitHandler}>
<button type="button" onClick={() => handleAdd()}>
Add Input
</button>
{fields.map((field, idx) => {
return (
<div key={`${idx}`}>
<input
type="text"
placeholder="Enter text"
value={field || ""}
onChange={(e) => handleChange(idx, e)}
/>
<button type="button" onClick={() => handleRemove(idx)}>
X
</button>
</div>
);
})}
<button className="margin-top" type="submit">
Submit
</button>
</form>
</div>
);
}
export default App;

Transfer Data from child component to parent component on React

I want to transfer a variable from search component as "child" to API component as "Parent". I did it with event for another part of codes but I don't know how did work exactly for a variable on my codes.
I want send "apiUrl" to parent. When user click on "current" get new location and generate new apiUrl, then send it to parent component for other stuff
Child:
import React from "react";
import "./Search.css";
const Search = function (props) {
const handleChange = (event) => {
props.onchange(event.target.value);
};
const handleSubmit = (event) => {
event.preventDefault();
props.onsubmit(event.target.value);
};
const navigation = (event) => {
event.preventDefault();
navigator.geolocation.getCurrentPosition(showPosition);
};
const showPosition = (position) => {
let latitude = position.coords.latitude;
let longitude = position.coords.longitude;
let latandlon = `lat=${latitude}&lon=${longitude}`;
let apiKey = "23422500afd990f6bd64b60f46cf509a";
let unit = "metric";
let apiUrl = `https://api.openweathermap.org/data/2.5/weather?${latandlon}&appid=${apiKey}&units=${unit}
`;
};
return (
<form className="form" onSubmit={handleSubmit}>
<div className="input-group">
<input
type="search"
className="form-control me-1"
placeholder="Enter City Name"
aria-label="City Name"
aria-describedby="basic-addon2"
onChange={handleChange}
/>
<div className="input-group-append">
<button className="btn btn-outline-secondary me-1" type="submit">
Search
</button>
<button
className="btn btn-outline-secondary me-1"
type="button"
onClick={navigation}
>
Current
</button>
</div>
</div>
</form>
);
};
export default Search;
Parent:
import React, { useState, useEffect } from "react";
import axios from "axios";
import Search from "./Search";
import ShowCurrentLocation from "./ShowCurrentLocation";
import HumidityAndWind from "./HumidityAndWind";
import CurrentStatus from "./CurrentStatus";
import ShowCurrentDay from "./ShowCurrentDay";
import CurrentDegree from "./CurrentDegree";
const Api = function (props) {
let [searchcity, setSearchcity] = useState("Tehran");
const [value, setValue] = useState("");
const [loader, setLoader] = useState(false);
const [weatherdata, setWeatherdata] = useState("");
const onchange = (data) => {
setValue(data);
};
const onsubmit = () => {
setSearchcity(value);
searchcity = value;
callApi();
};
// eslint-disable-next-line react-hooks/exhaustive-deps
useEffect(callApi, []);
function callApi() {
const apiKey = "23422500afd990f6bd64b60f46cf509a";
let units = "metric";
let apiUrl = `https://api.openweathermap.org/data/2.5/weather?q=${searchcity}&appid=${apiKey}&units=${units}`;
return axios.get(apiUrl).then(getWeatherData);
}
function getWeatherData(response) {
setWeatherdata({
temprature: Math.round(response.data.main.temp),
humidity: response.data.main.humidity,
wind: response.data.wind.speed,
description: response.data.weather[0].description,
city: response.data.name,
country: response.data.sys.country,
});
setLoader(true);
}
if (loader) {
return (
<div>
<div className="row">
<div className="col-md-9">
<Search
data1={searchcity}
onsubmit={(event) => {
onsubmit(event);
}}
data2={value}
onchange={(event) => {
onchange(event);
}}
/>
</div>
<div className="col-md-3 my-auto text-center">
<ShowCurrentLocation
data1={weatherdata.city}
data2={weatherdata.country}
/>
</div>
</div>
<div className="row my-auto">
<div className="col-md-7 my-auto">
<div className="row ">
<div className="col-6 my-auto text-start">
<div>
<HumidityAndWind
data1={weatherdata.humidity}
data2={weatherdata.wind}
/>
</div>
</div>
<div className="col-6 my-auto text-center">
<div>
<ShowCurrentDay />
</div>
</div>
</div>
</div>
<div className="col-md-5 my-auto">
<div className="row">
<div className="col-6 my-auto text-center">
<div>
<CurrentStatus data={weatherdata.description} />
</div>
</div>
<div className="col-6 my-auto text-center">
<CurrentDegree data={weatherdata.temprature} />
</div>
</div>
</div>
</div>
</div>
);
} else {
return "Loader";
}
};
export default Api;
You can't pass data or variable from your children to parent. But you can create some function from parent and pass it into a child that you want and the function is receive parameter for passing your data from children to parent. You can use useState to if you want, and pass that into your children component.
Example using useState:
ParentComponent
import { useState } from "react";
import ChildrenComponent from "./ChildrenComponent";
const ParentComponent = () => {
const [dataFromChild, setDataFromChild] = useState("");
console.log(dataFromChild);
return (
<div>
<ChildrenComponent setDataFromChild={setDataFromChild} />
</div>
);
};
export default ParentComponent;
ChildrenComponent
import { useState } from "react";
const ChildrenComponent = ({ setDataFromChild }) => {
const [data, setData] = useState("");
const handleChange = (e) => {
setData(e.target.value);
};
setDataFromChild(data);
return (
<div>
<label htmlFor="data"></label>
<input type="text" id="data" name="data" onChange={handleChange} />
<span>Its Data: </span>
<span>{data}</span>
</div>
);
};
export default ChildrenComponent;
so in above example we can access data on children component on parent component through function setDataFromChild using useState. Whenever the data onchildren change, the parent dataFromParent should be change to.

Component getting re rendered multiple times in react hooks

Since I am pretty new to react hooks, I am unable to understand some part of the existing code why my component is re-rendering multiple times when the state of an attribute gets changed. Below is the component code. I have added console.log for better understanding.
import React, { useState, useRef } from 'react';
import api from '../api/api';
import { UPLOAD_DATA } from '../api/urls';
import Alert from '../layout/alerts/Alerts';
const StudentDetailsView = ({ symbol }) => {
console.log("inside StudentDetailsView");
const initialState = {
form: {
qualification: symbol.qualification,
profession: symbol.profession
}
};
const [loading, setLoading] = useState(false);
const [errors, setErrors] = useState(null);
const [editFlag, setEditFlag] = useState(false);
const [inputs, setInputs] = useState(initialState);
console.log("before dataUpdated");
const [dataUpdated, setDataUpdated] =useState(false);
console.log("after dataUpdated");
const formRef = useRef(null);
const handleCancel = () => {
setEditFlag(false);
setInputs(initialState);
};
const handleSubmit = (e) => {
console.log("inside handleSumbit");
const form = formRef.current;
e.preventDefault();
e.stopPropagation();
form.classList.add('was-validated');
if (form.checkValidity()) {
callback();
}
};
const callback = ()=> {
setLoading(true);
const formData = new FormData();
formData.append('model', new Blob([JSON.stringify(inputs.form)], {
type: 'application/json'
}));
api.multipartEdit(UPLOAD_DATA, formData)
.then(response => {
setInputs(inputs => ({
...inputs,
form: {
qualification: response.data.qualification,
profession: response.data.profession
}
}));
setErrors(null);
setDataUpdated(true);
})
.catch(error => {
setErrors(error);
})
.finally(() => {
setLoading(false);
setEditFlag(false);
});
}
const handleInputChange = (event) => {
event.persist();
setInputs(inputs => ({
...inputs,
form: {
...inputs.form,
[event.target.name]: event.target.value
}
}));
}
return (
<div>
{
errors &&
<Alert type={errors.type} title={errors.title} description={errors.description} id="alert" />
}
<div >
{editFlag ? (
<div >
</div>
) :
(<div className="edit">
<button type="button" onClick={() => setEditFlag(!editFlag)}>
Edit
</button>
</div>)
}
</div>
<div>
<form className="needs-validation" onSubmit={handleSubmit} ref={formRef} noValidate>
{
editFlag ? (<div className="update-cancel-button">
<button className="btn btn-primary" type="submit" >
{loading ? (
<div className="spinner-border uxf-spinner-border-sm">
<span className="sr-only">Loading...</span>
</div>) : 'Update'}
</button>
<button className="btn btn-secondary cancel-button" type="button" onClick={handleCancel}>Cancel</button>
</div>) : <div></div>
}
<dl className="uxf-dl uxf-dl-horizontal">
<dt>Name</dt>
<dd>{symbol.name}</dd>
<dt>Age</dt>
<dd>{symbol.age}</dd>
<dt>Qualification</dt>
{editFlag ?
(<dd>
<textarea className="form-control" name="qualification" id="qualification"
value={inputs.form.qualification}
onChange={handleInputChange}
maxLength="255"></textarea>
<div className="invalid-feedback">
Please provide a Qualification.
</div>
</dd>)
:
(<dd>{dataUpdated ? (inputs.form.qualification ? inputs.form.qualification : '-') : (symbol.qualification ? symbol.qualification : '-')}</dd>)
}
<dt>Profession</dt>
{editFlag ?
(<dd>
<textarea className="form-control" name="profession" id="profession"
value={inputs.form.profession}
onChange={handleInputChange}
minLength="1"
maxLength="1000"
required></textarea>
<div className="invalid-feedback">
Please provide a Profession.
</div>
</dd>)
:
(<dd>{dataUpdated ? inputs.form.profession : symbol.profession}</dd>)
}
</dl>
</form>
</div>
</div>
);
}
export default StudentDetailsView;
Since my component is getting re-rendered, my state values which are getting set in the code (eg, dataUpdated) are getting updated with the default value again and again. How do I prevent this from happening? Please see the below images for better understanding.
(Showing the mockup of the edit component as the actual data was showing in the actual edit component)
I have clicked the edit button once and then clicked the cancel button once and this is the console log got generated.
Please uase spread operators on initializing or settingup states
const [inputs, setInputs] = useState({...initialState});
const handleCancel = () => {
setEditFlag(false);
setInputs({...initialState});
};

Categories

Resources