尝试编辑我的表单以更新用户详细信息,但表单在响应中拒绝更新

时间:2019-03-10 13:22:17

标签: javascript reactjs frontend

我正在尝试更新表单上的用户详细信息。我创建了一个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);

enter image description here

3 个答案:

答案 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,
          }
    )
    }