How to design State for Multiple objects using react-redux? - reactjs

I need to create multiple medicine objects here. I just want to change state into array of objects. How to do that effectively? Also, want to implement controlled component for multiple medicine objects form.
Here's my component for a single medicine object:
export class MedicineForm extends Component {
state = {
medicine_name: "",
details: ""
}
static propTypes = {
postMedicine: PropTypes.func.isRequired
}
onChange = e => {
this.setState({
[e.target.name]: e.target.value
})
}
onSubmit = e => {
e.preventDefault()
const { medicine_name, details } = this.state
const medicine = { medicine_name, details }
this.props.postMedicine(medicine)
// Following code works as desired. Need to change state in this JSON Array of objects.
// this.props.postMedicine([
// {
// "id": 14,
// "medicine_name": "many5",
// "details": "sdknas"
// },
// {
// "id": 15,
// "medicine_name": "many6",
// "details": "sdknas"
// }
// ])
}
render() {
const { medicine_name, details } = this.state
return (
<Fragment>
<h1>Add Medicine</h1>
<form className="card card-body" onSubmit={this.onSubmit}>
<div className="form-row">
<div className="form-group col-md-3">
<label htmlFor="medicine_name">Medicine Name</label>
<input type="text" className="form-control" name="medicine_name" id="medicine_name" placeholder="Medicine Name" value={medicine_name} onChange={this.onChange} />
</div>
<div className="form-group col-md-3">
<label htmlFor="details">Details</label>
<input type="text" className="form-control" name="details" id="details" placeholder="Details" value={details} onChange={this.onChange} />
</div>
<div className="form-group mx-auto mt-3">
<button type="submit" className="btn btn-primary btn-lg">
Submit
</button>
</div>
</div>
</form>
</Fragment>
)
}
}
In actions, I have added following postMedicine method:
export const postMedicine = (medicine) => dispatch => {
axios.post('./api/medicine/', medicine)
.then(res => {
dispatch({
type: POST_MEDICINE,
payload: res.data
})
})
.catch(err => console.log(err))
}

//this is one row, add multiple rows as needed
state = {
medicines: [{medicine_name: "",
details: ""
}]
}
//other code
onChange = (e, i) => {
const newMedicines = this.state.medicines;
newMedicines[i] = {[e.target.name]: e.target.value, ...newMedicines[i]}
this.setState({medicines: newMedicines})
}
onSubmit = e => {
e.preventDefault()
const { medicine_name, details } = this.state
const medicine = { medicine_name, details }
this.props.postMedicine(medicine)
// Following code works as desired. Need to change state in this JSON Array of objects.
// this.props.postMedicine(this.state.medicines)
}
<form className="card card-body" onSubmit={this.onSubmit}>
{this.state.medicines.map((m, i) => (<div className="form-row">
<div className="form-group col-md-3">
<label htmlFor="medicine_name">Medicine Name</label>
<input type="text" className="form-control" name="medicine_name" id="medicine_name" placeholder="Medicine Name" value={m.medicine_name} onChange={(e) => this.onChange(e, i)} />
</div>
<div className="form-group col-md-3">
<label htmlFor="details">Details</label>
<input type="text" className="form-control" name="details" id="details" placeholder="Details" value={m.details} onChange={(e) => this.onChange(e, i)} />
</div>
<div className="form-group mx-auto mt-3">
<button type="submit" className="btn btn-primary btn-lg">
Submit
</button>
</div>
</div>))}
</form>

Form component has two parameter (aka props).
first one is item, wich determines how many form do you need.
1 form means you have group of two inputs [medicine_name,details]
2 = 4 input (2 group)
...etc
and second props is function named formHandler.
wich lifting data from child
export class MedicineForm extends Component {
state = {
medicine: [],
};
static propTypes = {
postMedicine: PropTypes.func.isRequired,
};
formHandler = (value) => {
this.setState({ medicine: value });
};
onSubmit = (e) => {
e.preventDefault();
this.props.postMedicine(this.medicine);
};
render() {
return (
<>
<h1>Add Medicine</h1>
{JSON.stringify(this.state.medicine)}
<form className="card card-body" onSubmit={this.onSubmit}>
<Form item="4" formHandler={this.formHandler} />
<div className="form-group mx-auto mt-3">
<button type="submit" className="btn btn-primary btn-lg">
Submit
</button>
</div>
</form>
</>
);
}
}
Form Component
class Form extends Component {
constructor(props) {
super(props);
}
state = {
medicine: [...Array(+this.props.item)].map((_, idx) => ({
id: idx + 1,
medicine_name: "",
details: "",
})),
};
static propTypes = {
item: PropTypes.string,
formHandler: PropTypes.func,
};
onChange = ({ target: { id, name, value } }) => {
this.setState((prevState) => {
const medicine = prevState.medicine.map((item) =>
item.id === Number(id) ? { ...item, [name]: value } : item
);
this.props.formHandler(
medicine.filter((item) => item["medicine_name"] || item["details"])
);
return {
medicine,
};
});
};
render() {
return (
<div className="form-row">
{this.state.medicine.map((item, id) => (
<div key={item.id}>
<div className="form-group col-md-3">
<label htmlFor="medicine_name">Medicine Name</label>
<input
type="text"
className="form-control"
name="medicine_name"
id={item.id}
value={item.medicine_name}
placeholder="Medicine Name"
onChange={this.onChange}
/>
</div>
<div className="form-group col-md-3">
<label htmlFor="details">Details</label>
<input
type="text"
className="form-control"
name="details"
id={item.id}
value={item.details}
placeholder="Details"
onChange={this.onChange}
/>
</div>
</div>
))}
</div>
);
}
}
there is check if object has some value then lifting data.
you can change logic optional
medicine.filter((item) => item["medicine_name"] || item["details"])

You could do something like this in redux store:
[
{ id: 1, medicineName: '', details: '' },
{ id: 2, medicineName: '', details: '' },
...
]
And to make your input fields controlled just handle the state in the component.

Related

React - edit profile -first display read only fields and click on edit make fields editable

<div>
<label>Last Name</label>
<input
type="text"
name="lastName"
defaultValue={userData.lastName}
onChange={(ev) => this.setState({ lastName: ev.target.value })}
/>
</div>
I have some input fields on the screen.When the page loads first time , I am displaying readonly values from the redux store.On click of edit button , I want fields to become editable with the existing values.( i have state which corresponds to each field of the form).DefaultValue is from redux store .but onClick of save of new fields , I am only getting vlaues for fields which I have modified ,otherfields coming as blank.Any help pls?
/* eslint-disable react/destructuring-assignment */
/* eslint-disable react/forbid-prop-types */
/* eslint-disable no-nested-ternary */
import React, { Component } from 'react';
import { connect } from 'react-redux';
import PropTypes from 'prop-types';
import { eventsActions } from '../../store/actions/index';
class UserAccount extends Component {
//console.log(this.props);
constructor(props) {
console.log('props --- ', props.userData);
super();
this.state = {
username: props.userData.username,
firstName: props.userData.firstName,
lastName: props.userData.lastName,
// profilePic: '',
email: props.userData.email,
addressUnit: props.userData.addressUnit,
addressStreet: props.userData.addressStreet,
addressCity: props.userData.addressCity,
addressZip: props.userData.addressZIP,
addressState: props.userData.addressState,
isEditing: false,
};
this.toggleEdit = this.toggleEdit.bind(this);
}
componentDidMount() {
const { loadUserDetails } = this.props;
loadUserDetails();
}
toggleEdit() {
console.log('toggleEdit is called here ----');
this.setState({ isEditing: !this.state.isEditing });
}
handleChange = (event) => {
console.log('event ---- ', event);
this.setState({ [event.target.name]: event.target.value });
};
updateUser = (e) => {
console.log('updateUser is called ---');
e.preventDefault();
const {
username,
firstName,
lastName,
email,
addressUnit,
addressStreet,
addressCity,
addressZip,
addressState,
} = this.state;
const { editUser } = this.props;
console.log('for updating user --- ', this.state);
editUser(this.state);
};
render() {
const { userData } = this.props;
const {
username,
firstName,
lastName,
email,
addressUnit,
addressStreet,
addressCity,
addressZip,
addressState,
isEditing,
} = this.state;
console.log('userData --- ', userData);
console.log('isEditing ---- ', isEditing);
return (
<div>
{isEditing ? (
<div>
<div>
<label>First Name</label>
<input
type="text"
name="firstName"
// ref={firstName}
value={firstName}
onChange={this.handleChange}
/>
</div>
<div>
<label>Last Name</label>
<input
type="text"
name="lastName"
defaultValue={userData.lastName}
onChange={(ev) => this.setState({ lastName: ev.target.value })}
/>
</div>
<div>
<label>Email</label>
<input
type="text"
name="email"
value={userData.email}
onChange={(ev) => this.setState({ email: ev.target.value })}
/>
</div>
<div>
<label>UserName</label>
<input
type="text"
name="username"
value={userData.username}
onChange={(ev) => this.setState({ username: ev.target.value })}
/>
</div>
<div>
<label>Address Unit</label>
<input
type="text"
name="addressUnit"
value={userData.addressUnit}
onChange={(ev) =>
this.setState({ addressUnit: ev.target.value })
}
/>
</div>
<div>
<label>Address Street</label>
<input
type="text"
name="addressStreet"
value={userData.addressStreet}
onChange={(ev) =>
this.setState({ addressStreet: ev.target.value })
}
/>
</div>
<div>
<label>Address City</label>
<input
type="text"
name="addressCity"
value={userData.addressCity}
onChange={(ev) =>
this.setState({ addressCity: ev.target.value })
}
/>
</div>
<div>
<label>Address State</label>
<input
type="text"
name="addressState"
value={userData.addressState}
onChange={(ev) =>
this.setState({ addressState: ev.target.value })
}
/>
</div>
<div>
<label>Address Zip</label>
<input
type="text"
name="addressZip"
value={userData.addressZIP}
onChange={(ev) =>
this.setState({ addressZip: ev.target.value })
}
/>
</div>
<button type="submit" onClick={this.updateUser}>
Save
</button>
</div>
) : (
<div>
<form>
<div>
<label>First Name:</label>
<label> {userData.firstName}</label>
</div>
<div>
<label>Last Name:</label>
<label> {userData.lastName}</label>
</div>
<div>
<label>Email:</label>
<label> {userData.email}</label>
</div>
<div>
<label>UserName:</label>
<label> {userData.username}</label>
</div>
<div>
<label>Address Unit:</label>
<label> {userData.addressUnit}</label>
</div>
<div>
<label>Address Street:</label>
<label> {userData.addressStreet}</label>
</div>
<div>
<label>Address City:</label>
<label> {userData.addressCity}</label>
</div>
<div>
<label>Address State:</label>
<label> {userData.addressState}</label>
</div>
<div>
<label>Address Zip:</label>
<label> {userData.addressZIP}</label>
</div>
<button type="submit" onClick={this.toggleEdit}>
edit
</button>
</form>
</div>
)}
</div>
);
}
}
const mapStateToProps = (state) => {
console.log('state in UserProfile in mapStatetoProps --- ', state);
return { userData: state.events.user };
};
const mapDispatchToProps = (dispatch) => {
return {
loadUserDetails: (userId) => {
console.log('disptach is called for loadUserDetails --');
dispatch(eventsActions.fetchUserDetails(userId));
},
};
};
UserAccount.propTypes = {
loadUserDetails: PropTypes.func.isRequired,
userData: PropTypes.object.isRequired,
};
export default connect(mapStateToProps, mapDispatchToProps)(UserAccount);
You could e.g. initialize your state with values from redux store.
state = {
lastName: this.props.userData.lastName,
firstName: this.props.userData.lastName,
}; // and so on
Then, even if not modified, state will store the correct data.
Note: Remember to add value prop to the input:
<input onChange={} value={this.state.lastName} />
If your data comes from async request:
componentDidUpdate(prevProps) {
if (!prevProps.userData && this.props.userData){
this.setState({ firstName: this.props.userData.firstName });
}
}

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"
/>

React component is not re-rendered after the state is changed with a dropdown list [react hooks]

I have the following React component (using hooks), which lists a number of Tasks as a dropdown list. When an item is selected from the list, I want to display an Update form. This works only when an item is selected for the first time. When I select a new item, nothing happens (although console.log(e.target.value); prints the correct value). I store the selected task's id in st_taskId.
I wonder if you see any issues in the code below:
const ManageReviewTasks = props => {
const reviewRoundId = props.match.params.reviewRoundId;
const [st_taskId, set_taskId] = useState();
useEffect(() => {
if (props.loading == false && st_taskId == null)
props.fetchReviewTasksByReviewRound(reviewRoundId);
}, [reviewRoundId, st_taskId]);
if (props.loading == true) {
return <div>Loading...</div>;
}
return (
<>
{props.reviewTasks && (
<div>
<h3>Configure the Review Tasks</h3>
<br />
{
<div>
<div>
<h4>
Tasks for <span className="font-italic">students receiving</span> feedback:
</h4>
<select
className="form-control"
onChange={e => {
e.preventDefault();
console.log(e.target.value);
set_taskId(e.target.value);
}}>
<option>--SELECT--</option>
{Object.keys(props.reviewTasks).map(id => {
const task = props.reviewTasks[id];
{
if (task.isForStudent) {
return (
<option key={id} id={id} value={id}>
{task.title}
</option>
);
}
}
})}
</select>
</div>
{props.reviewTasks[st_taskId] && (
<UpdateReviewTaskForm task={props.reviewTasks[st_taskId]} />
)}
</div>
}
</div>
)}
</>
);
};
Below is the code for the UpdateReviewTaskForm component:
const UpdateReviewTaskForm = (props) => {
const [st_Title, set_Title] = useState(props.task.title);
const [st_Description, set_Description] = useState(RichTextEditor.createValueFromString(props.task.description, 'html'));
const [st_startDate, set_startDate] = useState(new Date(props.task.startDate.replace('-', '/')));
const [st_DueDate, set_DueDate] = useState(new Date(props.task.dueDate.replace('-', '/')));
const handleCancelClick = (event) => {
event.preventDefault();
history.goBack();
}
const onSubmit_saveTask = (e) => {
e.preventDefault();
props.updateReviewTask({
Id: props.task.id,
Title: st_Title,
Description: st_Description.toString('html'),
StartDate: format(st_startDate, 'DD/MM/YYYY'),
DueDate: format(st_DueDate, 'DD/MM/YYYY'),
})
}
if (props.loading)
return <div>Updating...</div>
return (
<div>
<br/>
<br/>
<div className="p-3 bg-light">
<h3 className="text-info">Update the Task:</h3>
{
props.task &&
<form onSubmit={onSubmit_saveTask}>
<div className="form-group">
<label>Enter the title</label>
<input
//placeholder="Enter a title..."
value={st_Title}
onChange={(event) => { set_Title(event.target.value) }}
className="form-control" />
</div>
<div className="form-group">
<label>Enter a description for the assessment</label>
<RichTextEditor
value={st_Description}
onChange={set_Description}
/>
</div>
<div className="form-group">
<label>Start date to start: </label>
<DatePicker
className="form-control"
selected={st_startDate}
onChange={(date) => set_startDate(date)}
/>
</div>
<div className="form-group">
<label>Due date to complete: </label>
<DatePicker
className="form-control"
selected={st_DueDate}
onChange={(date) => set_DueDate(date)}
/>
</div>
<br />
<button type="submit" className="btn btn-primary">Submit</button>
<button type="reset" className="btn btn-light" onClick={handleCancelClick}>Cancel</button>
</form>
}
</div>
</div>
)
}
Because you are using internal state in UpdateReviewTaskForm, even if this component re-render for the second time, its state will not be reset (to the default value props.task.title for example).
One way to force the state to reset is to use a key prop in UpdateReviewTaskForm like this :
{props.reviewTasks[st_taskId] && (
<UpdateReviewTaskForm key={st_taskId} task={props.reviewTasks[st_taskId]} />
)}
Another way is to use useEffect inside UpdateReviewTaskForm to run when props.task change
useEffect(() => {
// reset the state here
}, [props.task])

Grabbing React form field values for submission

Given a React form, I'm having trouble getting the value from the selected radio button, and text box if other is selected. I should be able to pass the fields into the send() for the post, but not sure how to grab them.
class CancelSurvey extends React.Component {
constructor (props) {
super(props)
this.state = {
reasons: [],
reason: {}
}
this.processData = this.processData.bind(this)
this.handleSubmit = this.handleSubmit.bind(this)
this.otherSelected = this.state.reason === "otheroption";
}
componentDidMount () {
this.fetchContent(this.processData)
}
/**
* Fetch reasons
*/
fetchContent (cb) {
superagent
.get('/api/user/survey')
.then(cb)
}
/**
* Set state after reasons have been fetched
* #param data
*/
processData (data) {
this.setState({
reasons: data.body
})
}
handleSubmit (e) {
e.preventDefault()
let reason = this.state.reason
if (reason === 'otheroption') {
reason = this.state.otherreason
}
console.log(reason)
superagent
.post('/api/user/survey')
.send({
optionId: this.state.reason.reason_id,
optionText: this.state.reason.client_reason,
otherReasonText: this.state.otherreason
})
.then(function (res) {
console.log('Survey Sent!')
})
}
/**
* render
*/
render (props) {
const content = this.props.config.contentStrings
const reason = this.state.reasons.map((reason, i) => {
return (
<div className='fieldset__item' key={i}>
<label>{reason.client_reason}</label>
<input type='radio'
id={reason.reason_id}
value={reason.client_reason}
name='reason'
checked={this.state.reason.reason_id === reason.reason_id}
onChange={() => this.setState({reason})} />
</div>
)
})
return (
<div className='survey'>
<h2 className='heading md'>{content.memberCancel.exitSurvey.heading}</h2>
<p className='subpara'>{content.memberCancel.exitSurvey.subHeading}</p>
<form id='exit-survey' onSubmit={this.handleSubmit}>
<fieldset className='fieldset'>
{ reason }
<label>Other reason not included above:</label>
<input type='radio'
id='otheroption'
name='reason'
value={this.state.reason.otherreason}
onChange={() => this.setState({reason:{reason_id: 70, client_reason: 'other'}})} />
<input className='valid'
type='text'
id='otheroption'
name='othertext'
placeholder={content.memberCancel.exitSurvey.reasonPlaceholder}
onChange={(event) => this.setState({otherreason: event.target.value})} />
</fieldset>
<div className='footer-links'>
<button className='btn btn--primary btn--lg' onClick={this.handleSubmit}>{content.memberCancel.exitSurvey.button}</button>
</div>
</form>
</div>
)
}
}
export default CancelSurvey
Your variables aren't correct. I've update them to what I think is correct.
handleSubmit (e) {
e.preventDefault()
superagent
.post('/api/user/survey')
.send({
optionId: this.state.reason.reason_id,
optionText: this.state.reason.client_reason,
otherReasonText: this.state.reason.otherreason
})
.then(function (res) {
console.log('Survey Sent!')
})
.catch(function (err) {
console.log('Survey submission went wrong...')
})
}
/**
* render
*/
render (props) {
const content = this.props.config.contentStrings
const reason = this.state.reasons.map((reason, i) => {
return (
<div className='fieldset__item' key={i}>
<label>{reason.client_reason}</label>
<input
type='radio'
id={reason.reason_id}
name='reason'
checked={this.state.reason.reason_id === reason.reason_id}
value={reason.client_reason}
onChange={() => this.setState({reason})} />
</div>
)
})
return (
<div className='survey'>
<h2 className='heading md'>{content.memberCancel.exitSurvey.heading}</h2>
<p className='subpara'>{content.memberCancel.exitSurvey.subHeading}</p>
<form id='exit-survey' onSubmit={this.handleSubmit}>
<fieldset className='fieldset'>
{ reason }
<label>Other reason not included above:</label>
<input type='radio'
id='otheroption'
name='otheroption'
value={this.state.reason.otherreason}
checked={this.state.reason.reason_id === 0}
onChange={() => this.setState({ reason: {reason_id: 0, client_reason: ""} })} />
<input className='valid'
type='text'
id='othertext'
name='othertext'
value={this.state.reason.otherreason}
placeholder={content.memberCancel.exitSurvey.reasonPlaceholder}
onChange={(event) => this.setState({ reason: {reason_id: 0, client_reason: "", otherreason: event.target.value} })} />
</fieldset>
<div className='footer-links'>
<button className='btn btn--primary btn--lg' onClick={this.handleSubmit}>{content.memberCancel.exitSurvey.button}</button>
</div>
</form>
</div>
);
}

Unable to type in input after adding value in React Js

I have tried with the following code with react js
import React, { Component } from 'react';
import Sidebar from './../Sidebar';
import Header from './../Header';
import {get_profile} from './../services/Services';
import $ from 'jquery';
export default class Profile extends Component {
constructor(props) {
super(props);
this.state = { userDetails: '' } ;
}
componentWillMount() {
$(window).scrollTop(0)
console.log('sdfds')
get_profile().then((response) => {
var userResults = $.parseJSON(response.text);
this.setState({ userDetails: userResults.response });
console.log(userResults);
}).catch((error) => {
//alert(error)
console.log(error);
});
}
handleChange(event) {
console.log(event.target.id)
this.setState({[event.target.name]: event.target.value});
}
render() {
return (
<div className="admin-panel">
<Sidebar />
<Header />
<div className="main-content">
<div className="contents">
<div className="container-fluid">
<div className="row">
<div className="col-sm-6">
<h2 className="page-title">Profile</h2>
<div className="form-group">
<label >First Name</label>
<input type="text" id="firstName" className="form-control" value={this.state.userDetails.firstName} />
</div>
<div className="form-group">
<label >Last Name</label>
<input type="text" id="lastName" className="form-control" value={this.state.userDetails.lastName} />
</div>
<div className="form-group">
<label >Email</label>
<input type="text" id="email" name="email" className="form-control" value={this.state.userDetails.email} />
</div>
<button type="button" className="btn btn-squared btn-success margin-inline" onClick={(e)=> {this.profileUpdate()}}>Update</button>
</div>
</div>
</div>
</div>
</div>
</div>
);
}
}
After fetching the results i'm unable to edit the input box value. I have tried with defaultValue but that also not working for me. I'm struck with this issue, Kindly help me to solve the issue.
Just pass an onChange handler to the input which will update the value of the corresponding key of userDetails like this:
<input
...
value={this.state.userDetails.firstName}
onChange={this.onChange}
/>
onChange(e) {
this.setState((previousState) => {
const userDetails = previousState.userDetails
return { userDetails: {...userDetails, firstName: e.target.value} }
})
}
or you can write a common onChange function like this:
<input
...
value={this.state.userDetails.firstName}
onChange={(e) => {this.onChange(e.target.value, 'firstName')}}
/>
<input
...
value={this.state.userDetails.lastName}
onChange={(e) => {this.onChange(e.target.value, 'lastName')}}
/>
<input
...
value={this.state.userDetails.email}
onChange={(e) => {this.onChange(e.target.value, 'email')}}
/>
onChange(value, key) {
this.setState((previousState) => {
const userDetails = previousState.userDetails
return { userDetails: {...userDetails, [key]: value} }
})
}

Resources