我正在尝试更新表单上的用户详细信息。我创建了一个UpdateForm组件,该组件运行componentDidMount来获取特定用户,并且我还使用了静态getDerivedStateFromProps来用该用户详细信息预先填充表单。但是当涉及直接从前端编辑表单时,我无法编辑预先填充的表单。
这是我的代码:
import React, { Component } from 'react';
import Cookie from 'cookies-js';
import { connect } from 'react-redux';
import PropTypes from 'prop-types';
import fetchSingleMasterAgent from
'../../../actions/ownerActions/masterAgentsActions/fetchSingleMasterAgent';
import TextField from '../../common/TextField';
import UserInputValidation from '../../../middlewares/validateMasterAgentInput';
/**
* @class UpdateMasterAgentForm
*/
class UpdateMasterAgentForm extends Component {
state = {
id: this.props.singleMasterAgent ? this.props.singleMasterAgent.id : null,
fullname: this.props.singleMasterAgent ? this.props.singleMasterAgent.fullname : '',
username: this.props.singleMasterAgent ? this.props.singleMasterAgent.username : '',
address: this.props.singleMasterAgent ? this.props.singleMasterAgent.address : '',
email: this.props.singleMasterAgent ? this.props.singleMasterAgent.email : '',
password: this.props.singleMasterAgent ? this.props.singleMasterAgent.password : '',
phoneNumber: this.props.singleMasterAgent ? this.props.singleMasterAgent.phoneNumber : '',
device1: this.props.singleMasterAgent ? this.props.singleMasterAgent.device1 : '',
device2: this.props.singleMasterAgent ? this.props.singleMasterAgent.device2 : '',
errors: {}
}
/**
*
* @param {*} prevProps
* @returns {*} - single master agent object
*/
componentDidMount() {
const phoneNumber = Cookie.get('number');
const { fetchSingleMasterAgent } = this.props;
fetchSingleMasterAgent(phoneNumber);
}
/**
*
* @param {*} nextProps
* @returns {*} - single master agent object
*/
static getDerivedStateFromProps(nextProps) {
return {
id: nextProps.singleMasterAgent.id,
fullname: nextProps.singleMasterAgent.fullname,
username: nextProps.singleMasterAgent.username,
address: nextProps.singleMasterAgent.address,
email: nextProps.singleMasterAgent.email,
phoneNumber: `${nextProps.singleMasterAgent.phoneNumber}`,
password: nextProps.singleMasterAgent.password,
device1: nextProps.singleMasterAgent.device1,
device2: nextProps.singleMasterAgent.device2,
};
}
/**
*
* @param {*} event
* @returns {*} - state
*/
onChange = (event) => {
const { errors } = this.state;
if (errors[event.target.name]) {
const newErrors = Object.assign({}, errors);
delete newErrors[event.target.name];
this.setState({
[event.target.name]: event.target.value,
errors: newErrors
});
} else {
this.setState({
[event.target.name]: event.target.value
});
}
}
/**
*
* @param {*} event
* @returns {*} - state
*/
onSubmit = (event) => {
event.preventDefault();
// const { CreateMasterAgentRequest } = this.props;
if (this.isValid()) {
this.setState({ errors: {}, isLoading: true });
// CreateMasterAgentRequest(this.state);
}
}
/**
*
* @param {*} event
* @returns {*} - state
*/
isValid = () => {
const { errors, isValid } = UserInputValidation.masterAgentInputValidation(
this.state
);
if (!isValid) {
this.setState({ errors, password: '' });
}
return isValid;
}
/**
*
* @returns {*} - render
*/
render() {
const {
phoneNumber,
username,
email,
fullname,
address,
password,
device1,
device2,
errors
} = this.state;
const updateMasterAgentForm = (
<div className="row">
<div className="col-xl-12">
<section className="hk-sec-wrapper">
<h5 className="hk-sec-title">Edit Form</h5>
<p className="mb-25">Hello Owner kindly use the form below to update a given master agent of your choice.</p>
<hr />
<div className="row">
<div className="col-sm">
<form>
<div className="row">
<div className="col-md-6 form-group">
<label htmlFor="firstName">Fullname</label>
<TextField
error={errors.fullname}
className="myfullname"
id="firstName"
placeholder="Enter Fullname"
onChange={this.onChange}
field="fullname"
value={fullname || ''}
type="text"
/>
</div>
<div className="col-md-6 form-group">
<label htmlFor="lastName">Username</label>
<TextField
error={errors.username}
className="myusername"
id="lastName"
placeholder="Enter Username"
onChange={this.onChange}
field="username"
value={username || ''}
type="text"
/>
</div>
</div>
<div className="row">
<div className="col-md-6 form-group">
<label htmlFor="firstName">Address</label>
<TextField
error={errors.address}
className="myaddress"
id="address"
placeholder="Enter Address"
onChange={this.onChange}
field="address"
value={address || ''}
type="text"
/>
</div>
<div className="col-md-6 form-group">
<label htmlFor="email">Email</label>
<TextField
error={errors.email}
className="myemail"
id="email"
placeholder="you@example.com"
type="email"
onChange={this.onChange}
field="email"
value={email || ''}
/>
</div>
</div>
<div className="row">
<div className=" col-md-6 form-group">
<label htmlFor="email">Password</label>
<TextField
error={errors.password}
className="mypassword"
id="password"
placeholder="Password"
type="password"
onChange={this.onChange}
field="password"
value={password || ''}
/>
</div>
<div className="col-md-6 form-group">
<label htmlFor="firstName">Phone Number</label>
<TextField
error={errors.phoneNumber}
className="myphonenumber"
id="phoneNumber"
type="text"
placeholder="Enter Phone Number"
onChange={this.onChange}
field="phoneNumber"
value={phoneNumber || ''}
/>
</div>
</div>
<div className="row">
<div className=" col-md-6 form-group">
<label htmlFor="email">POS Devices</label>
<TextField
error={errors.device1}
className="mydevice1"
placeholder="Number of POS devices"
type="text"
onChange={this.onChange}
field="device1"
value={device1 || ''}
/>
</div>
<div className="col-md-6 form-group">
<label htmlFor="firstName">IGR Devices</label>
<TextField
error={errors.device2}
className="mydevice2"
id="device2"
type="text"
placeholder="Number of IGR devices"
onChange={this.onChange}
field="device2"
value={device2 || ''}
/>
</div>
</div>
<hr />
<div className="text-center">
<button className="btn btn-primary" type="submit">Update Master Agent</button>
</div>
</form>
</div>
</div>
</section>
</div>
</div>
);
return <div>{updateMasterAgentForm}</div>;
}
}
UpdateMasterAgentForm.propTypes = {
singleMasterAgent: PropTypes.shape({}).isRequired,
fetchSingleMasterAgent: PropTypes.func.isRequired
};
const mapStateToProps = state => ({
singleMasterAgent: state.fetchSingleMasterAgent.singleMasterAgent,
});
export default connect(mapStateToProps, { fetchSingleMasterAgent })(UpdateMasterAgentForm);
答案 0 :(得分:0)
简短的回答,getDerivedStateFromProps
始终将您的状态“重置”到您获取的代理。 https://reactjs.org/docs/react-component.html#static-getderivedstatefromprops说,它不仅用于更改道具,还用于每次更新。因此,一旦删除它,问题就是如何正确初始化表单值。
// from props
// remove state = and add a constructor
constructor(props) {
const agent = props.agent
this.state = {
// get from lodash, less code
id: get(agent, 'id', null),
username: get(argent, 'username', ''),
... and on and on
}
}
// from your request
init = (singleMasterAgent) => {
// pick from 'lodash', or you can keep verbose native style
this.setState(pick(singleMasterAgent, ['id', 'username', ... all your values]))
}
componentDidMount() {
const phoneNumber = Cookie.get('number');
const { fetchSingleMasterAgent } = this.props;
fetchSingleMasterAgent()
// add this line
.then(this.init)
}
我要补充一点,鉴于您的API调用没有条件,您似乎总是在获取用户,因此您不需要“ props”初始化,因此我将删除构造函数并添加初始值像这样说回来。
state = { id: null, username: '', ... and everything.}
如果仅依靠API调用来填充表单值,则也可以删除mapStateToProps
。
答案 1 :(得分:0)
在代码中将属性field
更改为name
:
<TextField
className="mydevice2"
error={errors.device2}
id="device2"
name="device2"
onChange={this.onChange}
placeholder="Number of IGR devices"
type="text"
value={device2 || ''}
/>
答案 2 :(得分:0)
使用componentDidUpdate
代替getDerivedStateFromProps
。
componentDidUpdate(prevProps, prevState){
if(
this.props./*any your prop or data fetched status from API call*/ === value &&
prevProps./*same prop name*/ !== value) {
this.setState(
{
id: this.props.singleMasterAgent.id,
fullname: this.props.singleMasterAgent.fullname,
username: this.props.singleMasterAgent.username,
address: this.props.singleMasterAgent.address,
email: this.props.singleMasterAgent.email,
phoneNumber: `${this.props.singleMasterAgent.phoneNumber}`,
password: this.props.singleMasterAgent.password,
device1: this.props.singleMasterAgent.device1,
device2: this.props.singleMasterAgent.device2,
}
)
}